• 爬虫基础知识


    概述

    定义:

      爬虫的本质:通过编写程序模拟浏览器上网,获取页面源码或在动态数据,通过解析返回结果获取想要的数据的过程

    分类:

    1. 通用爬虫:获取整张页面的源码数据
    2. 聚焦爬虫:获取指定区域的数据,如页面加载时的一些动态数据
    3. 增量式爬虫:获取网站更新的数据

    常见的反扒机制:

    1. robots.txt协议:可以在网页后面加上robots.txt,该协议规定允许哪些服务器爬取数据,但该协议像"无人地摊一样".(解决方法,当作看不到即可)
    2. UA协议:在请求头中有一个User-agent字段,该字段的值是关于浏览器的信息,有些网站没有该字段不让访问(解决方法:复制浏览器的请求ua字段)
    3. 验证码:通过输入验证码才能访问(采用云打码等第三方平台解码,然后填写到验证码输入框
    4. cookie:没有携带cookie的不允许访问(采用自动cookie处理即requests模块的Session实例化的对象代替requests)
    5. 检测ip:对于短期内多次数访问封ip(在requests请求中添加代理ip参数即可)
    6. 动态参数:通过给之前的网页分配一个隐藏的参数,页面请求是需要携带该参数,否则不允许访问(解析源码获取该参数)
    7. 动态加载数据:用户在浏览器的操作加载不同数据,(通过获取动态加载数据的url请求获取队形数据)

    requests模块

    requses模块是可以通过模拟浏览器发送请求获取页面的响应数据,安装模块:pip install requests

    使用步骤:

    1. 指定url,请求头以及请求数据
    2. 向服务器发送数据
    3. 获取和解析数据
    4. 持久化存储

    示例

    # 需求:爬取搜狗指定词条搜索后的页面数据
    import requests
    
    # 1. 指定URL
    url = "https://www.baidu.com/"
    # 请求头数据
    headers = {
        # 从浏览器复制过来的UA
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36"
    }
    #请求数据,可根据实际情况决定要不要
    data = {
        "kw""cat"
    }
    
    # 2. 向服务器发送请求,该请求是get请求,如果是pose请求则如注释所示
    response = requests.get(url=url, headers=headers,params=data)
    # response = requests.post(url=url, data=data, headers=headers)
    
    # 3. 获取响应数据,
    page_text = response.text
    # 如果返回的是json数据
    # data = response.json()
    # 如果返回的是视频或者图片等文件数据
    # data = response.content
    
    
    # 4. 持久化存储
    with open('./lijie.html', 'w', encoding="utf-8") as f:
        f.write(page_text)

    页面数据解析

    当页面返回json()数据和content数据,可以直接将数据存储到本地,但如果返回的数据是text数据,通常返回的是html源码,这个时候就需要解析源码获取数据,常用的解析源码模块有bs4和lxml,其中,bs4模块是基于lxml模块的,所以想要使用就必须安装两个模块,通过pip install ba4和pip install lxml下载安装

    bs4

    通过模块的BeautifulSoup类来实例化一个对象soup

    常用方法和属性

    1. 根据标签名查找标签:soup.a
    2. 获取标签属性:soup.a.attrs(获取所有属性名和值),soup.a.attrs["href"](获取a标签的href属性),soup.a["href"](获取href属性)
    3. 获取文本内容:soup.string(不能获取标签内部的标签的文本属性),soup.text/soup.get_text()(获取标签下所有文本)
    4. 获取第一个符合要求的标签:soup.find("标签名",属性名=“属性值”),如soup.find("a", class="test")
    5. 查找所有符合要求的标签:soup.find_all("标签名",属性名=“属性值”),如soup.find_all("a", class="test")
    6. 通过选择器查找标签:soup.select(标签选择器) #css中支持的这类基本都支持

    案例

    # 爬取诗词名句网http://www.shicimingju.com/book/index.html 前100个小说的所有内容, 每一个文章存一个txt文件, 并保存到文件夹中
    
    import requests,os
    from bs4 import BeautifulSoup
    
    # 请求url,获取全部书籍都信息
    url = "http://www.shicimingju.com/book/index.html"
    headers = {
        # UA伪装
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36"
    }
    response_text = requests.get(url=url,headers=headers).text
    
    # 实例化一个soup对象
    soup = BeautifulSoup(response_text,"lxml")
    
    # 通过选择器获取标签多个列表
    book_detail_list = soup.select(".bookmark-list ul li a")
    book_title = []
    
    # 获取标签后得到标签的属性和文本
    for i in book_detail_list:
        dic = {
            "title":i.text,
            "url":"http://www.shicimingju.com" + i.attrs["href"]
        }
        book_title.append(dic)
    
    # 创建保存数据的目录
    if not os.path.exists("./book"):
        os.mkdir("./book")
    
    # 循环获取书籍的内容
    for book in book_title:
        # 获取书籍rl
        book_url = book["url"]
        # 获取某本书籍的源码
        book_data = requests.get(url=book_url,headers=headers).text
        
        # 判断之前是否以及爬取过
        if os.path.exists("./book/" + book["title"] + ".txt"):
            continue
        
        # 实例化一个书籍的soup对象
        chapter_soup = BeautifulSoup(book_data,"lxml")
        
        # 查看书籍章节信息
        chapter_detail_list = chapter_soup.select(".book-mulu ul li a")
        filename = "book/"+book["title"] + ".txt"
        f = open(filename,"w",encoding="utf-8")
        # 获取书籍每章内容并保存在本地
        for i in chapter_detail_list:
            chapter_url = "http://www.shicimingju.com" + i.attrs["href"]
            response_data = requests.get(url=chapter_url,headers=headers).text
            soup = BeautifulSoup(response_data,"lxml")
            if len(soup.select(".www-main-container")) > 0:
                continue
            data = soup.select(".www-main-container")[0].text
            f.write(data)
            f.write("
    ")
        f.close()

    lxml

    通过该模块解析数据好处是通用性强,通过模块提供的etree类实例化一个类对象tree,通过该对象加载数据后的xpath方法可以定位到标签,然后通过方法或属性来得到数据

    实例化对象:tree = etree()

    加载数据:tree.HTML(response_text)

    定位数据:tree.xpath('//div[@id="test"]/div/p/a')

    获取文本:tree.xpath('//div[@id="test"]/div/p/a/text()').extract()

    获取属性:tree.xpath('//div[@id="test"]/div/p/a/@href').extract()

    代码解析://后面的div表示定位到div标签,[]内部写的是标签属性,后面的/div/p/a/表示定位到div标签下的div标签下的p标签下的a标签,text()获取文本属性的对象,@href获取a标签的href属性对象,extract表是将对象转化成列表,通过列表就可以获取值,示例

    # 爬取梨视频里面体育版块最热和最新的视频(.mp4的格式)并下载到本地, 保存到文件夹中https://www.pearvideo.com/category_9
    
    
    import requests,os
    from lxml import etree
    
    # 指定url
    url = "https://www.pearvideo.com/category_4"
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36"
    }
    
    # 获取源码
    response_text = requests.get(url=url,headers=headers).text
    
    # 正则表达式
    ex = 'srcUrl="(.*?)".*?vdoUrl=srcUrl'
    # 实例化etree对象
    tree = etree.HTML(response_text)
    # 获取所有视频详情页的url, | 代表或运算
    tree_list = tree.xpath('//ul[@class="listvideo-list clearfix"]/li/div/a/@href | //ul[@class="category-list clearfix"]/li/div/a/@href')
    data_url_list = []
    for new_url in tree_list:
        # 获取详情页url
        new_url = "https://www.pearvideo.com/" + new_url
        # 向详情页发送请求获取源码数据
        detail_text = requests.get(url=new_url,headers=headers).text
        
        # 通过正则湖区视频下载url
        data_list = re.findall(ex,detail_text,re.S)
        if len(data_list)>0:
            data_url_list.append(data_list[0])
    
    if not os.path.exists("./video"):
        os.mkdir("./video")
    
    
    for data_url in data_url_list:
        filename = "video/" + data_url.split("/")[-1]
        print(filename)
        with open(filename,"wb") as f:
            response = requests.get(url=data_url,headers=headers)
            f.write(response.content)

     

  • 相关阅读:
    UrlRewriter配置IIS支持伪静态
    Linux 安装PAE内核
    Tmux入门教程
    Tmux与Oh-my-zsh环境整合
    MySQL Route负载均衡与读写分离Docker环境使用
    MySQL数据表的基本操作
    Git安全配置
    GitLab使用自定义端口
    Gitlab搭建安装及使用中遇到的问题。
    执行Docker命令报错解决办法
  • 原文地址:https://www.cnblogs.com/mark--ping/p/11761662.html
Copyright © 2020-2023  润新知