• 爬虫-数据解析


    数据解析

    • 聚焦爬虫:数据解析

    • 数据解析的原理

      • 标签定位
      • 获取标签中的数据
    • python实现数据解析的方式:

      • 正则
        • 通用性强
        • 编写复杂
        • 不能爬取带标签的文本内容
      • bs4
        • 可以爬取带标签的文本内容
        • 只能在python中使用
        • 编写简单
      • xpath
        • 通用性强
        • 编写程度简单
        • 不能爬取带标签的文本内容
      • pyquery
        • python自带的一个解析方式,不常用,通用性差
    • 使用正则进行数据解析:爬取糗事百科中的图片数据

      #使用正则进行数据解析:爬取糗事百科中的图片数据
      import requests
      import re,os
      from urllib import request
      if not os.path.exists('./qiutuLibs'):
          os.mkdir('./qiutuLibs')
      headers = {
      'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36'
      }
      #定义一个通用的url模板,使用%d实现更换页码
      url = 'https://www.qiushibaike.com/pic/page/%d/?s=5201079'
      for page in range(1,36):
          #某一个页码对应的完整的url
          new_url = format(url%page)
          #使用通用爬虫对当前url对应的一整张页面源码数据进行爬取
          page_text = requests.get(url=new_url,headers=headers).text
          #数据解析:所有的图片地址
          ex = '<div class="thumb">.*?<img src="(.*?)" alt.*?</div>'
          #re.S是正则中专门用来处理换行的
          img_src = re.findall(ex,page_text,re.S)
          for src in img_src:
              src = 'https:'+src
              #切片把路径的最后端作为图片名字
              img_name = src.split('/')[-1]
              img_path = './qiutuLibs/'+img_name
              request.urlretrieve(src,img_path)
              print(img_name,'下载成功')
      

    bs4解析

    • 解析原理

      • 实例化一个BeautifulSoup对象,并且即将被解析的源码数据加载到该对象中
      • 调用BeautifulSoup对象中相关的属性和方法进行标签定位和数据提取
    • 环境的安装

      • pip install bs4
    • BeautifulSoup对象的实例化

      • BeautifulSoup(fp,'lxml'):是将本地的一个html文档中的源码数据加载到该对象中
      • BeautifulSoup(page_text,'lxml'):是将从互联网上获取的页面源码数据加载到该对象中
    • 引用案例

      from bs4 import BeautifulSoup
      fp = open('./test.html','r',encoding='utf-8')
      soup = BeautifulSoup(fp,'lxml')
      #标签定位
          # soup.tagName:定位到的是源码中第一次出现的该标签
          # print(soup.div)
          # soup.find('tagName',attrName='value')属性定位
          # print(soup.find('div',class_='tang')),属性上要加下划线,返回定位的单数
          # print(soup.find_all('div',class_='tang')),属性上要加下划线,返回定位的复数
          # select('选择器'):标签,类,id,层级 选择器
          # print(soup.select('#feng'))id选择器
          # print(soup.select('.tang > ul > li'))类选择器
          # print(soup.select('.tang  li')) 空格表示的是多个层级,大于号表示一个层级
      #数据提取
          # print(soup.p.string) ,获取的是标签中直系的文本内容
          # print(soup.p.text)  ,获取的是标签中所有的文本内容
          # print(soup.p.get_text()) ,获取的是标签中所有的文本内容
      
      # 区别
      	# print(soup.select('.song')[0].get_text())
      
      #取属性
      	# print(soup.img['src'])
      
    • 爬取三国演义小说全篇内容

      #爬取三国演义小说全篇内容
      import requests
      from bs4 import BeautifulSoup
      url = 'http://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/73.0.3683.103 Safari/537.36'
      }
      
      page_text = requests.get(url=url,headers=headers).text
      #数据解析,章节标题
      soup = BeautifulSoup(page_text,'lxml')
      a_list = soup.select('.book-mulu>ul>li>a')
      fp = open('./sanguo.txt','w',encoding='utf-8')
      for a in a_list:
          title = a.string
          detail_url = 'http://www.shicimingju.com'+a['href']
          #获取详情页数据
          detail_page_text = requests.get(url=detail_url,headers=headers).text
          soup = BeautifulSoup(detail_page_text, 'lxml')
          content = soup.find('div',class_="chapter_content").text
          fp.write(title+':'+content+'
      ')
          print(title,'下载完毕')
      fp.flush()
      fp.close()
      #bs4缺点在于只能在python中使用,但是可以爬取带标签的文本内容
      

    xpath解析

    • 解析原理

      • 实例化一个etree的对象,并且将页面源码数据加载到该对象中
      • 可以通过调用etree对象的xpath方法结合着不同类型的xpath表达式进行标签定位和数据提取
    • 环境安装

      • pip install lxml
    • etree对象的实例化

      • etree.parse('filePath')
      • etree.HTML(page_text)
    • xpath方法使用

      from lxml import etree #引入模块
      tree = etree.parse('./test/html')
      title = tree.xpath('/html/head/title')#从根节点开始一层一层的寻找指定的标签
      titles = tree.xpath('//title')#不是从根节点开始寻找
      #属性定位
      div = tree.xpath('//div[@class="song"]')
      
      #索引定位
      li = tree.xpath('//div[@class="tang"]/ul/li[5]') #索引是从1开始
      lis = tree.xpath('//div[@class="tang"]//li[5]') #索引是从1开始
      
      #取值 /text()直系的文本内容  //text()所有的文本内容
      a = tree.xpath('//div[@class="tang"]/a[1]/text()')
      print(''.join(a))
      divs = tree.xpath('//div[@class="song"]//text()')
      
      #取属性
      a_href = tree.xpath('//div[@class="song:]/a[1]/@href')
      print(a_href[0])
      
    • 爬取boss中岗位的名称,薪资,公司名称

      #爬取boss中岗位的名称,薪资,公司名称
      import requests
      from lxml import etree
      url = 'https://www.zhipin.com/c101010100/?query=java&page={}&ka=page-{}'
      headers = {
      'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36'
      }
      fp = open('./java.txt','w',encoding='utf-8')
      for page in range(1,11):
          new_url = url.format(page,page)
          page_text = requests.get(url=new_url,headers=headers).text
          #数据解析
          tree = etree.HTML(page_text)
          #数据的提取,xpath解析全局源码的内容不需要加'.'
          li_list = tree.xpath('//div[@class="job-list"]/ul/li')
          for li in li_list:
              #xpath解析指定标签局部内容需要加上'.'
              job_title = li.xpath('.//div[@class="job-title"]/text()')[0]
              salary = li.xpath('.//div[@class="info-primary"]/h3/a/span/text()')[0]
              company = li.xpath('.//div[@class="company-text"]/h3/a/text()')[0]
              fp.write(job_title+'    '+salary+'  '+company+'
      ')
      fp.flush()
      fp.close()
      
    • 爬取 http://pic.netbian.com/4kmeinv/ 所有的图片

      import requests
      from lxml import etree
      from urllib import request
      import os
      if not os.path.exists('./4k'):
          os.mkdir('./4k')
      url = 'http://pic.netbian.com/4kmeinv/index_%d.html'
      
      headers = {
      'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36'
      }
      #拿到页面
      for page in range(1,197):
          if page == 1:
              new_url = 'http://pic.netbian.com/4kmeinv/'
          else:
              new_url = format(url%page)
          response = requests.get(url=new_url,headers=headers)
          # response.encoding='utf-8'
          page_text = response.text
          #数据解析,图片地址
          tree = etree.HTML(page_text)
          li_list = tree.xpath('//div[@class="slist"]/ul/li')
          for li in li_list:
              img_src = 'http://pic.netbian.com' + li.xpath('./a/img/@src')[0]
              img_name = li.xpath('./a/img/@alt')[0]+'.jpg'
              img_name = img_name.encode('iso-8859-1').decode('gbk')
              img_path = './4k/'+img_name
              request.urlretrieve(img_src,img_path)
              print(img_name,'下载成功')
      
    • 爬取全国城市的名称https://www.aqistudy.cn/historydata/

      #爬取全国城市的名称https://www.aqistudy.cn/historydata/
      import requests
      from lxml import etree
      url = 'https://www.aqistudy.cn/historydata/'
      headers = {
      'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36'
      }
      page_text = requests.get(url=url,headers=headers).text
      #数据解析:全国城市名称和热门城市名称
      tree = etree.HTML(page_text)
      # host_city_name = tree.xpath('//div[@class="bottom"]/ul/li/a/text()')
      # all_city_name = tree.xpath('//div[@class="bottom"]/ul/div[2]/li/a/text()')
      #xpath表达式可以使用按位或"|"的方式多个合成一个,拓展性强
      city_name = tree.xpath('//div[@class="bottom"]/ul/li/a/text() | //div[@class="bottom"]/ul/div[2]/li/a/text()')
      print(city_name)
      
      
    • 爬取58二手房的房源信息(房屋名称,价格,概况(存在于详情页中的))

      # 爬取58二手房的房源信息(房屋名称,价格,概况(存在于详情页中的))
      import requests
      from lxml import etree
      #创建一个url模板
      url = 'https://bj.58.com/shahe/ershoufang/pn%d/'
      headers = {
      'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36'
      }
      for page in range(1,3):
          new_url = format(url%page)
          page_text = requests.get(url=new_url,headers=headers).text
          # 数据解析:详情页的url,房屋名称和价格
          tree = etree.HTML(page_text)
          li_list = tree.xpath('/html/body/div[5]/div[5]/div[1]/ul/li')
          for li in li_list:
              title = li.xpath('./div[@class="list-info"]/h2/a/text()')[0]
              #//text()会拿到所有的文本数据,使用join拼接转换为字符串操作
              price = ''.join(li.xpath('./div[3]//text()'))
              detail_url = li.xpath('./div[2]/h2/a/@href')[0]
              # 对详情页发起请求获取源码数据并且解析出概述对应的数据值
              detail_page_text = requests.get(url=detail_url,headers=headers).text
              detail_tree = etree.HTML(detail_page_text)
              desc = ''.join(detail_tree.xpath('//*[@id="generalSituation"]//text()'))
              print(title,price,desc)
      
    • http://sc.chinaz.com/tupian/rentiyishu.html 当前页中所有的图片进行下载,懒加载

      # http://sc.chinaz.com/tupian/rentiyishu.html 当前页中所有的图片进行下载,懒加载
      import requests
      from lxml import etree
      
      url = 'http://sc.chinaz.com/tupian/rentiyishu.html'
      headers = {
      'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36'
      }
      #获取页面文本数据
      response = requests.get(url=url,headers=headers)
      #图片涉及2进制,需要使用指定utf8编码,再text,解决乱码
      response.encoding='utf-8'
      page_text = response.text
      #解析页面数据(获取页面中的图片链接)
      #创建etree对象
      tree = etree.HTML(page_text)
      div_list = tree.xpath('//*[@id="container"]/div')
      #解析获取图片地址和图片的名称
      for div in div_list:
          image_url = div.xpath('.//img/@src2')#src2伪属性
          image_name = div.xpath('.//img/@alt')
          print(image_url)  # 打印图片链接
          print(image_name)  # 打印图片名称
      
  • 相关阅读:
    Spring IoC容器实现
    Spring IoC简介及使用
    tomcat使用及原理
    tomcat的连接数与线程池
    tomcat配置文件server.xml
    java源码之Comparable和Comparator
    java源码之TreeSet
    25 二叉搜索树与双向链表
    24 复杂链表的复制
    条款04:确定对象被使用前已被初始化
  • 原文地址:https://www.cnblogs.com/Godisgirl/p/11017368.html
Copyright © 2020-2023  润新知