爬虫的数据解析, 正则 ,bs ,xpath

爬虫的数据解析

两种爬取图片的方法

  • 第一种: 使用with open 保存为文件
import requests
headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36'
}

img_url = 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1559019106959&di=3aa954df95d2e55083d85de8391118c5&imgtype=0&src=http%3A%2F%2Fimg3.duitang.com%2Fuploads%2Fitem%2F201601%2F28%2F20160128195606_xvawC.jpeg'

img_data = requests.get(url=img_url,headers=headers).content

with open('./meinv.jpg','wb') as fp:
    fp.write(img_data)
  • 第二种: 使用urllib模块
from urllib import request
img_url = 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1559019106959&di=3aa954df95d2e55083d85de8391118c5&imgtype=0&src=http%3A%2F%2Fimg3.duitang.com%2Fuploads%2Fitem%2F201601%2F28%2F20160128195606_xvawC.jpeg'
request.urlretrieve(img_url,'./meishaonv.jpg')

数据解析

常用的python数据解析有四种方式:

  • 正则
  • xpath
  • bs4
  • pyquery

数据解析的原理:

  • 标签的定位
  • 提取标签中存储的文本数据或者标签属性中存储的数据

1.正则解析:

  • 示例
    • 需求:爬取糗事百科中所有的糗图图片数据
    • 实现:
      • 检查页面中的图片数据是否为动态加载的
      • 将当前页面的源码数据请求到
      • 使用正则表达式定位相关的img标签,然后获取img的src属性值
      • 对src的属性值发起请求获取图片数据
      • 持久化存储图片数据

对页面的分析:

可以看到要提取img标签中的src属性

<div class="thumb">

<a href="/article/121858876" target="_blank">
<img src="//pic.qiushibaike.com/system/pictures/12185/121858876/medium/VFMNF2Z1GNEYXR3A.jpg" alt="求大神制作">
</a>

</div>

实现:

import os

import requests
import re
from urllib import request
if not os.path.exists('./qiutu'):
    os.mkdir('./qiutu')
headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36'
}

url = 'https://www.qiushibaike.com/pic/'
page_text = requests.get(url=url,headers=headers).text

ex = '<div class="thumb">.*?<img src="(.*?)" alt.*?</div>'
img_url = re.findall(ex,page_text,re.S)
for url in img_url:
    url = 'https:'+url
    img_name = url.split('/')[-1]
    img_path = './qiutu/'+img_name
    request.urlretrieve(url,img_path)
    print(img_name,'下载成功!!!')

2.bs4解析(beautifulsoup4)

  • 解析原理:
    • 实例化一个Beautifulsoup的对象,且将页面源码数据加载到该对象中
    • 使用该对象的相关属性和方法实现标签定位和数据提取
  • 环境的安装:
    • pip install bs4
    • pip install lxml
  • 实例化Beautifulsoup对象
    • BeautifulSoup(page_text,'lxml'):将从互联网上请求到的页面源码数据加载到该对象中
    • BeautifulSoup(fp,'lxml'):将本地存储的一样页面源码数据加载到该对象中

bs4模块的基本使用

示例的文件为当前准备的test.html文件

from bs4 import BeautifulSoup

fp = open('./test.html','r',encoding='utf-8')
soup = BeautifulSoup(fp,'lxml')

1.soup.tagName:只可以定位到第一次出现的tagName标签

soup.title
soup.div

2.soup.find(‘tagName’)

#soup.find(‘tagName’)
soup.find('a')  # soup.a
#属性定位
soup.find('div',class_='song')

结果如下

<div class="song">
<p>李清照</p>
<p>王安石</p>
<p>苏轼</p>
<p>柳宗元</p>
<a href="http://www.song.com/" target="_self" title="赵匡胤">
<span>this is span</span>
		宋朝是最强大的王朝,不是军队的强大,而是经济很强大,国民都很有钱</a>
<a class="du" href="">总为浮云能蔽日,长安不见使人愁</a>
<img alt="" src="http://www.baidu.com/meinv.jpg"/>
</div>

3.find_all

soup.find_all(‘div’)[2]  # 找到所有的div标签中的第3个,

4.select(‘选择器’)

soup.select('.song')  # 找到类为.song的标签
soup.select('div')
soup.select('.tang > ul > li > a')
soup.select('.tang a')

示例:爬取古诗文网的三国演义小说

  • 页面数据是否为动态加载
  • 在首页中解析章节标题和标题对应的详情页的url
  • 对详情页url发起请求获取详情页的源码数据
  • 检查详情页是否存在动态加载的数据
  • 解析详情页中的章节内容
  • 持久化存储
url = 'http://www.shicimingju.com/book/sanguoyanyi.html'
page_text = requests.get(url=url,headers=headers).text
#数据解析:标题和url
soup = BeautifulSoup(page_text,'lxml')
li_list = soup.select('.book-mulu > ul > li')
fp = open('./sanguo.txt','w',encoding='utf-8')
for li in li_list:
    title = li.a.string
    detail_url = 'http://www.shicimingju.com'+li.a['href']
#     print(title,detail_url)
    #单独对详情页发起请求获取源码数据
    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+'\n'+content+'\n')
    print(title,':下载成功!')
    
fp.close()

3.xpath解析

  • 解析效率比较高
  • 通用性最强的
  • 环境安装:pip install lxml
  • 解析原理:
    • 实例化一个etree对象且将即将被解析的页面源码数据加载到该对象中
    • 使用etree对象中的xpath方法结合着xpath表达式进行标签定位和数据提取
  • 实例化etree对象
    • etree.parse('本地文件路径')
    • etree.HTML(page_text)
from lxml import etree
tree = etree.parse('./test.html')

定位title标签

tree.xpath('/html/head/title')
tree.xpath('/html//title')
tree.xpath('//title')


定位class=song的div

tree.xpath('//div[@class="song"]')
tree.xpath('//div[2]') #xpath表达式中的索引是从1开始

取文本

#取文本(获取李清照) /text()  //text()
tree.xpath('//div[@class="song"]/p[1]/text()')[0]
tree.xpath('//div[@class="song"]/text()')

爬取boss直聘的python爬虫岗位信息

解决报错信息: HTTPConnectionPool(host:XX)Max retries exceeded with url

  1. 及时断开连接:headers =
  2. 更换请求对应的ip
#boss直聘
url = 'https://www.zhipin.com/job_detail/?query=python%E7%88%AC%E8%99%AB&city=101010100&industry=&position='
page_text = requests.get(url=url,headers=headers).text

#数据解析(jobTitle,salary,company)
tree = etree.HTML(page_text)
li_list = tree.xpath('//div[@class="job-list"]/ul/li')
for li in li_list:
    title = li.xpath('.//div[@class="job-title"]/text()')[0]
    salary = li.xpath('.//span[@class="red"]/text()')[0]
    company = li.xpath('.//div[@class="company-text"]/h3/a/text()')[0]
    print(title,salary,company)
posted @ 2019-05-28 22:42  robertx  阅读(340)  评论(0编辑  收藏  举报