• 数据解析


    图片的爬取

    import requests
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36'
    }
    
    #法一
    url = 'https://pic.qiushibaike.com/system/pictures/12356/123563596/medium/MKTIXGAKTQHL81QP.jpg'
    img = requests.get(url=url,headers=headers).content  #重点!
    with open('./qiutu1.jpg','wb') as fp:
        fp.write(img)
    
    # 法二
    # 简洁,但是不能使用UA伪装
    from urllib import request
    
    url = 'https://pic.qiushibaike.com/system/pictures/12356/123563596/medium/MKTIXGAKTQHL81QP.jpg'
    request.urlretrieve(url,filename='./qiutu2.jpg')
    

    数据解析

    数据解析的作用?

    - 帮助我们实现聚焦爬虫(局部数据)
    

    数据解析的实现方式:

    - 正则
    - bs4
    - xpath(通用性最强)
    - pyquery(自己拓展)
    

    正则

    # 糗图1-3页的爬取
    # 1.使用通用爬虫爬取1-3页的页面源码
    # https://www.qiushibaike.com/imgrank/page/1/
    # https://www.qiushibaike.com/imgrank/page/2/
    # https://www.qiushibaike.com/imgrank/page/3/
        # 通用的url模板(不可变)
    
    import os
    import re
    from urllib import request
    import requests
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36'
    }
    
    dirName = './imgLib'
    if not os.path.exists(dirName):
        os.mkdir(dirName)
    
    url = 'https://www.qiushibaike.com/imgrank/page/%d/'
    for page in range(1,4):
        new_url = format(url%page)
        page_text = requests.get(new_url,headers=headers).text  # 每个页码对应一个页面源码的数据
        # 2.在通用爬虫的基础上实现聚焦爬虫(从页面源码解析出图片地址)
        reg = '<div class="thumb">.*?<img src="(.*?)" alt.*?</div>'
        img_src_list = re.findall(reg,page_text,re.S)
        for src in img_src_list:
            src = 'https:'+ src
            img_name = src.split('/')[-1]
            img_path = dirName + '/' + img_name  #./imgLib/xx.jpg
            request.urlretrieve(src,filename=img_path)
            print(img_name,'下载成功!')
    

    bs4

    • bs4解析
      • bs4解析的原理:
        • 实例化一个BeautifulSoup的对象,需要将即将被解析的页面源码加载到该对象中
        • 调用BeautifulSoup对象的相关方法和属性进行标签定位和数据提取
      • 环境的安装:
        • pip install bs4
        • pip install lxml
      • BeautifulSoup的实例化:
        • BeautifulSoup(fp,'lxml') 将本地存储的一个html文档中的数据加载到实例化的bs对象中
        • BeautifulSoup(page_text,'lxml') 将从互联网上获取的页面源码数据加载到bs对象中
      • 定位标签的操作
        • 标签定位:
          • soup.tagName 定位到第一个出现的tagName标签
        • 属性定位:
          • soup.find('tagName',attrName='value') 返回值为标签
          • soup.find_all('tagName',attrName='value') 返回值为列表(里面是标签,用下标获取标签)
          • class_ 因为class是关键字,不能作为参数!
        • 选择器定位:
          • soup.select('选择器')
          • 层级
            • soup.select('.xx > ul > li') >表示一个层级
            • soup.select('.xx li') 空格表示多个层级
          • 返回值为列表(用下标获取标签)
      • 取文本
        • 先定位
        • .string:获取直系的文本内容(如div标签中的p标签的文本就不能直接获取)
        • .text:获取所有的文本内容
      • 取属性
        • tagName['attrName']
    # 爬取三国整篇内容(章节名称+章节内容)  https://www.shicimingju.com/book/sanguoyanyi.html
    # 需求分析:在首页爬取章节名称,然后具体到每个章节里爬取章节内容
    from bs4 import BeautifulSoup
    import requests
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36'
    }
    
    fp = open('sanguo.txt','w',encoding='utf-8')
    
    main_url = 'https://www.shicimingju.com/book/sanguoyanyi.html'
    main_page = requests.get(url=main_url,headers=headers).text
    #解析出章节名称和章节内容页面的url
    soup = BeautifulSoup(main_page,'lxml')
    a_list = soup.select('.book-mulu > ul > li > a')  # 存放一个个a标签的列表 <a href="/book/sanguoyanyi/1.html">第一回·宴桃园豪杰三结义  斩黄巾英雄首立功</a>
    for a in a_list:
        title = a.string
        chapter_url = 'https://www.shicimingju.com' + a['href']
        content_page = requests.get(url=chapter_url,headers=headers).text
        #解析详情页中的章节内容
        soup = BeautifulSoup(content_page,'lxml')
        content = soup.find('div',class_='chapter_content').text
        fp.write(title + ':' + content + '
    ')
        print(title + '下载成功!')
    fp.close()
    

    xpath解析

    • xpath解析

      • xpath解析的实现原理
        • 实例化一个etree对象,然后将即将解析的页面源码加载到该对象中
        • 使用etree对象中的xpath方法结合不同形式的xpath表达式实现标签的定位
        • xpath中表达式是核心!
      • 环境安装
        • pip install lxml
      • etree对象的实例化
        • etree.parse('xxx.html') 本地
        • etree.HTML(page_text) 互联网
    • xpath表达式(xpath方法的返回值一定是一个列表)

      • 最左侧的/表示:xpath表达式一定要从根标签逐层进行标签查找和定位
      • 最左侧的//表示:xpath表达式可以从任意位置定位标签
      • 非最左侧的/表示:一个层级
      • 非最左侧的//表示:跨多个层级
      • 属性定位://tagName[@attrName="value"]
      • 索引定位://tagName[index] (从1开始)
    • 取文本:

      • /text() 取直系文本内容
      • //text() 取所有的文本内容
      • 举例:tree.xpath('//div[@id=xx]/text()')[0]
    • 取属性:

      • /@attrName
    # 爬取糗事百科的段子内容和作者名称
    import requests
    from lxml import etree
    
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36'
    }
    url = 'https://www.qiushibaike.com/text/'
    page_text = requests.get(url=url,headers=headers).text
    # 实例化etree对象
    tree = etree.HTML(page_text)
    # xpath方法定位标签
    content_div_list = tree.xpath('//div[@class="col1 old-style-col1"]/div')
    for content_div in content_div_list:
        author_name = content_div.xpath('./div[1]/a[2]/h2/text()')[0]  # 实现局部解析
        content = content_div.xpath('./a[1]/div/span//text()')
        content = ''.join(content)   # 可能取出多个,所以不能用索引取值,要将列表拼接成字符串!
        print(author_name,content)
    
    # http://pic.netbian.com/4kqiche/ 中文乱码的处理
    import requests
    from lxml import etree
    import os
    
    dirName = './carsLib'
    if not os.path.exists(dirName):
        os.mkdir(dirName)
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36'
    }
    url = 'http://pic.netbian.com/4kqiche/index_%d.html'
    for page in range(1,4):
        if page == 1:
            new_url = 'http://pic.netbian.com/4kqiche/'
        else:
            new_url = format(url%page)
        page_text = requests.get(url=new_url,headers=headers).text
        tree = etree.HTML(page_text)
        a_list = tree.xpath('//div[@class="slist"]/ul/li/a')
        for a in a_list:
            img_src = 'http://pic.netbian.com/'+a.xpath('./img/@src')[0]
            img_name = a.xpath('./b/text()')[0]
            img_name = img_name.encode('iso-8859-1').decode('gbk')   # 解决中文乱码的问题
            img_path = dirName+'/'+img_name+'.jpg'
            img_data = requests.get(url=img_src,headers=headers).content
            with open(img_path,'wb') as fp:
                fp.write(img_data)
                print(img_name,'下载成功!')
    
    # https://www.aqistudy.cn/historydata/  所有城市名称
    # 用|连接两个表达式
    
    url = 'https://www.aqistudy.cn/historydata/'
    page_text = requests.get(url=url,headers=headers).text
    tree = etree.HTML(page_text)
    # hot_cities = tree.xpath('//div[@class="hot"]/div[@class="bottom"]/ul/li/a/text()')
    # all_cities = tree.xpath('//div[@class="all"]/div[@class="bottom"]/ul/div[2]/li/a/text()')
    cities = tree.xpath('//div[@class="hot"]/div[@class="bottom"]/ul/li/a/text()|//div[@class="all"]/div[@class="bottom"]/ul/div[2]/li/a/text()')
    print(cities)
    

    数据解析的通用原理:

    - 聚焦爬虫爬取的数据一般存储在哪?
        - 存储在了相关标签之间
        - 相关标签的属性中(img/href...)
    - 1.定位标签
    - 2.取文本或取属性
  • 相关阅读:
    ThreadLocal源码分析与实践
    基于jdk1.8的LinkedList源码分析
    Spring编程式事务使用不当导致其他事务无法正常提交
    Spring计时器StopWatch使用
    工厂模式(Factory pattern)
    Spring Cloud Alibaba生态探索:Dubbo、Nacos及Sentinel的完美结合
    Spring Cloud Alibaba微服务生态的基础实践
    自己作图分析分布式技术架构演化的常用套路
    用一个实例项目重新认识分布式系统
    重温Java Web的技术细节
  • 原文地址:https://www.cnblogs.com/straightup/p/13664722.html
Copyright © 2020-2023  润新知