02 爬虫-数据解析

  • 数据解析
    • 数据解析的作用:
      • 可以帮助我们实现聚焦爬虫
    • 数据解析的实现方式:
      • 正则
      • bs4
      • xpath
      • pyquery
    • 数据解析的通用原理
      • 问题1:聚焦爬虫爬取的数据是存储在哪里的?
        • 都被存储在了相关的标签之中and相关标签的属性中
      • 1.定位标签
      • 2.取文本或者取属性

如何爬取图片

  • requests 的方式一:
import requests
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36',
}
url = 'https://pic.qiushibaike.com/system/pictures/12223/122231866/medium/IZ3H2HQN8W52V135.jpg'
img_data = requests.get(url,headers=headers).content  # byte类型数据
with open('./减肥.jpg','wb') as fp:
    fp.write(img_data)
  • request 的方式二 弊端:不能使用UA 伪装
from urllib import request
url ='https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1568112741761&di=e9f724b2c52bddbe93b98b1ede448bb7&imgtype=0&src=http%3A%2F%2Fwww.chinadaily.com.cn%2Fhqzx%2Fimages%2Fattachement%2Fjpg%2Fsite385%2F20120924%2F00221918200911ca40e52b.jpg'
request.urlretrieve(url,filename='./沙滩美女.jpg')
  • 正则——数据解析例子:
import re
import os
import requests
from urllib import request
#糗图爬取1-3页所有的图片
#1.使用通用爬虫将前3页对应的页面源码数据进行爬取
#通用的url模板(不可变)
dirName = './re_imagetest'
# UA 伪装
# headers = {
#     'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36',
# }

if not os.path.exists(dirName):
    os.mkdir(dirName)
url = 'https://www.qiushibaike.com/pic/page/%d/'
for page in range(1,4):
    new_url = format(url%page)
    print(new_url)
    page_text = requests.get(new_url,headers=headers).text # 每一个页码对应的页面源码数据
    # 在通用爬虫的基础上实现聚焦爬虫(每一个页码对应页面源码数据中解析出图片地址)
    ex = '<div class="thumb">.*?<img src="(.*?)" alt.*?</div>'
    img_src_list = re.findall(ex,page_text,re.S)  # 跨行
#     print(img_src_list)
    for src in img_src_list:
        src = 'https:' + src
        img_name = src.split('/')[-1]
#         print(img_name)
        img_path = dirName + '/' + img_name  #  /imgLibs/xxxx.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文档中的数据加载到实例化好的BeautifulSoup对象中
      • BeautifulSoup(page_text,‘lxml’):将从互联网上获取的页面源码数据加载到实例化好的BeautifulSoup对象中
  • 定位标签的操作:

    • soup.tagName:定位到第一个出现的tagName标签
    • 属性定位:soup.find(‘tagName’,attrName=‘value’)
    • 属性定位:soup.find_all(‘tagName’,attrName=‘value’),返回值为列表
    • 选择器定位:soup.select(‘选择器’)
      • 层级选择器:>表示一个层级 空格表示多个层级
  • 取文本

    • .string:获取直系的文本内容
    • .text:获取所有的文本内容
  • 取属性

    • tagName[‘attrName’]
  • bs4 示例
    test.html

<html lang="en">
<head>
	<meta charset="UTF-8" />
	<title>测试bs4</title>
</head>
<body>
	<div>
		<p>百里守约</p>
	</div>
	<div class="song">
		<p>李清照</p>
		<p>王安石</p>
		<p>苏轼</p>
		<p>柳宗元</p>
		<a href="http://www.song.com/" title="赵匡胤" target="_self">
			<span>this is span</span>
		宋朝是最强大的王朝,不是军队的强大,而是经济很强大,国民都很有钱</a>
		<a href="" class="du">总为浮云能蔽日,长安不见使人愁</a>
		<img src="http://www.baidu.com/meinv.jpg" alt="" />
	</div>
	<div class="tang">
		<ul>
			<li><a href="http://www.baidu.com" title="qing">清明时节雨纷纷,路上行人欲断魂,借问酒家何处有,牧童遥指杏花村</a></li>
			<li><a href="http://www.163.com" title="qin">秦时明月汉时关,万里长征人未还,但使龙城飞将在,不教胡马度阴山</a></li>
			<li><a href="http://www.126.com" alt="qi">岐王宅里寻常见,崔九堂前几度闻,正是江南好风景,落花时节又逢君</a></li>
			<li><a href="http://www.sina.com" class="du">杜甫</a></li>
			<li><a href="http://www.dudu.com" class="du">杜牧</a></li>
			<li><b>杜小月</b></li>
			<li><i>度蜜月</i></li>
			<li><a href="http://www.haha.com" id="feng">凤凰台上凤凰游,凤去台空江自流,吴宫花草埋幽径,晋代衣冠成古丘</a></li>
		</ul>
	</div>
</body>
</html>
  • bs4用法
from bs4 import BeautifulSoup
fp = open('./test.html','r',encoding='utf-8')
soup = BeautifulSoup(fp,'lxml')  # 本地存储的html
soup.div  # 第一个div
soup.find('div',class_='song')  # find只能找到符合要求的第一个标签,他返回的是一个对象
soup.find('a',id='feng')  # 根据id属性
soup.find_all('div',class_="song")  # 返回一个列表,列表里面是所有的符合要求的对象
soup.select('#feng')  # id 选择
soup.select('.tang > ul > li')
soup.select('.tang li')
a_tag = soup.select('#feng')[0]
a_tag.text
div = soup.div
div.string
div = soup.find('div',class_='song')
div.text  # 获取所有的文本内容
a_tag = soup.select('#feng')[0]
a_tag['href']
  • bs4爬取三国演义小说
#爬取三国整篇内容(章节名称+章节内容)http://www.shicimingju.com/book/sanguoyanyi.html
import requests
from bs4 import BeautifulSoup

main_url = 'http://www.shicimingju.com/book/sanguoyanyi.html'
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36',
}

fp = open('三国.txt','w',encoding='utf-8')
page_text = requests.get(main_url,headers=headers).text
# 解析出章节名称和章节详情页的 url
soup = BeautifulSoup(page_text,'lxml')
a_list = soup.select('.book-mulu > ul > li > a')  # 返回的列表中存储的是一个个a标签

for a in a_list:
    title = a.string # 章节名
    detail_url = 'http://www.shicimingju.com' + a['href']
    detail_page_text = requests.get(detail_url,headers=headers).text
    #解析详情页中的章节内容
    soup = BeautifulSoup(detail_page_text,'lxml')
    content = soup.find('div',class_="chapter_content").text
    fp.write(title + ':' + content + '\n')
    print(title,'下载成功!')
fp.close()
  • xpath解析

    • xpath解析的实现原理
      • 1.实例化一个etree的对象,然后将即将被解析的页面源码加载到改对象中
      • 2.使用etree对象中的xpath方法结合着不同形式的xpath表达式实现标签定位和数据提取
    • 环境安装:
      • pip install lxml
    • etree对象的实例化:
      • etree.parse(‘test.html’)
      • etree.HTML(page_text)
  • xpath表达式:xpath方法的返回值一定是一个列表

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

    • /text():直系文本内容
    • //text():所有的文本内容
  • 取属性:

    • /@attrName
      xpath 的用法
      使用的上面 test.html 文件
from lxml import etree
tree = etree.parse('./test.html')
tree.xpath('/html/head/title')
tree.xpath('//title')
tree.xpath('/html/body//p')
tree.xpath('//p')
tree.xpath('//div[@class="song"]')
tree.xpath('//li[7]')
tree.xpath('//a[@id="feng"]/text()')[0]
tree.xpath('//div[@class="song"]//text()')
tree.xpath('//a[@id="feng"]/@href')
  • 示例一:
import requests
#爬取糗百中的段子内容和作者名称
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36',
}
url = 'https://www.qiushibaike.com/text/'
page_text = requests.get(url,headers=headers).text

# 解析内容
tree = etree.HTML(page_text)
div_list = tree.xpath('//div[@id="content-left"]/div')

for div in div_list:
    author = div.xpath('./div[1]/a[2]/h2/text()')[0]  # 实现局部解析
    content = div.xpath('./a[1]/div/span//text()')
    content = ''.join(content)
    
    print(author,content)
  • 示例二:
    爬取图片 中文乱码的处理
#http://pic.netbian.com/4kmeinv/中文乱码的处理  
import os
import requests
from lxml import etree

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36',
}

dirName = './美女图片'
if not os.path.exists(dirName):
    os.mkdir(dirName)
url = 'http://pic.netbian.com/4kmeinv/index_%d.html'
for page in range(1,11):
    if page == 1:
        new_url = 'http://pic.netbian.com/4kmeinv/'
    else:
        new_url = format(url%page)
    page_text = requests.get(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:
#         print(a.xpath('./img/@src')[0])
        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_data = requests.get(img_src,headers=headers).content
        imgPath = dirName + '/' + img_name + '.jpg'
        with open(imgPath,'wb') as fp:
            fp.write(img_data)
            print(img_name,'下载成功!!!')        
#https://www.aqistudy.cn/historydata/所有城市名称
import requests
from lxml import etree

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36',
}
page_text = requests.get('https://www.aqistudy.cn/historydata/',headers=headers).text

tree = etree.HTML(page_text)
# hot_cities = tree.xpath('//div[@class="bottom"]/ul/li/a/text()')
# all_cities = tree.xpath('//div[@class="bottom"]/ul/div[2]/li/a/text()')
cities = tree.xpath('//div[@class="bottom"]/ul/div[2]/li/a/text() | //div[@class="bottom"]/ul/li/a/text()') #提高xpath的通用性
cities
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

尼古拉斯-kq

支持一下,感谢!!!!!!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值