Python爬虫(从requests到scrapy

爬虫

作者:Ychhh_


铺垫内容

爬虫分类

  • 通用爬虫:

    • 抓取系统重要组成部分
  • 聚焦爬虫:

    • 建立在通用爬虫的基础之上
    • 抓取的为抓取页面局部内容
  • 增量式爬虫:

    • 检测网站中数据的更新情况

反爬机制

  • 门户网站,可以通过指定相应的策略,防止爬虫程序进行数据的窃取
  • 反反爬策略:破解反爬策略,获取数据

相关协议

  • robots.txt 协议:
    • 君子协议。规定了网站中哪些数据可以被爬取,哪些不可以被爬取
  • http协议:
    • 常用客户端与服务器的通信协议
  • 常用请求头信息:
    • user-Agent:请求载体的身份标识
    • connection:请求完毕后是断开连接还是保持连接
  • 常用响应头信息:
    • content-type:服务器相应客户端的数据类型
  • https协议:
    • 安全的超文本传输协议
  • 加密方式:
    • 对称密钥加密:
      密文和密钥均由客户机发送给服务器
      缺陷:密钥和密文可能会被中间机构拦截

    • 非对称密钥加密:
      密文由客户机发送给服务器
      密钥由服务器发送给客户机
      缺陷:不能保证客户机拿到的密钥一定由服务器提供

    • 证书密钥加密(https):
      由第三方认证机制进行密钥防伪认证


requests模块

requests作用

模拟浏览器发送请求

  • response返回种类:
    • text:文本格式
    • json:json对象
    • content:图片格式

UA伪装(反爬机制)

门户网站若检测到请求载体为request而不是浏览器,则会使得拒绝访问


聚焦爬虫

数据解析分类

  • 正则
  • bs4
  • xpath

bs4

  • 数据解析原理
    1. 标签定位
    2. 提取标签属性中的数据值

  • bs4数据解析原理:

     1. 实例化beautysoup对象,并将源码数据加载到beautysoup中
     2. 通过调用beautysoup对象中相关属性和方法进行标签定位和数据提取
    
  • 属性定位:

    • soup.tagName:找到第一次出现的标签的属性
    • soup.find():
      1. find(tagName):等同于soup.tagName
      2. find(tagName,class / attr / id …):按照属性进行定位
    • soup.find_all():查找符合要求的所有标签(列表新式),也可以作为属性定位
    • soup.select():
      1. 标签选择器
      2. 层级选择器:
      - 父标签 > 子标签(一个层即)
      - ‘ ’空格表示多个层即
    • Attention:对于find和select的结果非同一对象
  • 获取标签中的内容:

    • soup.text
    • soup.string
    • soup.get_text()
  • 代码样例(三国演义爬取)

    import requests
    import json
    from bs4 import BeautifulSoup
    
    if __name__ == "__main__":
    
        url = "https://www.shicimingju.com/book/sanguoyanyi.html"
    
        headers = {
         
            "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.61 Safari/537.36"
        }
    
        response = requests.get(url=url,headers=headers)
        response.encoding = response.apparent_encoding #设置编码格式
        """
        其中 r.encoding 根据响应头中的 charset 判断网站编码,如果没有设置则默认返回 iso-8859-1 编码,而r.apparent_encoding
    则通过网页内容来判断其编码。令r.encoding=r.apparent_encoding就不会出现乱码问题。
        """
    
        html = response.text
    
        # print(html)
        soup = BeautifulSoup(html,'lxml')
        muluList = soup.select(".book-mulu a")
        muluRecord = []
        for mulu in muluList:
            muluRecord.append(mulu.text)
        pageNum = len(muluRecord)
        dataTotalUrl = "https://www.shicimingju.com/book/sanguoyanyi/%d.html"
        for i,title in enumerate(muluRecord):
            dataUrl = dataTotalUrl%(i + 1)
            response = requests.get(url=dataUrl,headers=headers)
            response.encoding = response.apparent_encoding
            dataHtml = response.text
    
            dataSoup = BeautifulSoup(dataHtml,'lxml')
    
    
            data = dataSoup.find("div",class_="chapter_content").text
            data = data.replace("  ","\n")
            path = r"C:\Users\Y_ch\Desktop\spider_test\data\text\sanguo\\" + title + ".txt"
            with open(path,'w',encoding="utf-8") as fp:
                fp.write(data)
                print("第%d篇下载完毕"%(i + 1)
    
    
    

xpath

  • 数据解析原理:

    1. 实例化etree对象,且需要将页面源码数据加载到被解析对象中去
    2. 调用etree中的方法,配合着etree中的xpath方法定位
  • 解析方法:

    1. 将本地的html源码数据加载到etree中
      • etree.parse(filepath)
    2. 可以将互联网上获得的源码数据加载到etree中去
      • etree.HTML(text)
  • xpath使用:

    • 绝对路径:/xx/xx/x
    • 省略路径://xx
    • 属性定位://tagName[@attr = “”]
    • 索引定位://tagName[@attr=""]/xx
    • 重复索引://tagName[@attr]//p[pos]
    • 文本获取://tagName/text()
    • 属性获取://tagName/@attr
  • 代码样例(4K图片爬取)

    import json
    from lxml import etree
    import requests
    
    if __name__ == "__main__":
        url = "https://pic.netbian.com/4kdongman/index_%d.html"
    
        headers = {
         
            "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.61 Safari/537.36"
        }
        pageNum = 2
    
        for page in range(pageNum):
            if page == 0:
                new_url = "https://pic.netbian.com/4kdongman/"
            else:
                new_url = url % (page + 1)
    
            response = requests.get(url=new_url, headers=headers)
    
            html_code = response.text
    
            tree = etree.HTML(html_code)
    
            urlList = tree.xpath("//ul[@class=\"clearfix\"]//img//@src")
    
            urlHead = "https://pic.netbian.com"
            path = r"C:\Users\Y_ch\Desktop\spider_test\data\pic\4K\\"
            picUrlList = []
            for index, eachUrl in enumerate(urlList):
                picUrl = urlHead + eachUrl
                picUrlList.append(picUrl)
    
            for index, picUrl in enumerate(picUrlList):
                picReq = requests.get(url=picUrl, headers=headers)
                pic = picReq.content
    
                picPath = path + str(page)+ "." +
  • 6
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值