我们首先回顾一下之前学习的requsets模块实现数据爬取的流程:
其实,在上述的流程中还需要较为重要的一步,就是在持久化存储之前需要进行指定数据解析。因此大多数情况下的需求,我们都会指定去使用聚焦爬虫,也就是爬取页面中指定部分的数据值,而不是整个页面的数据。因此,本次可能将详细介绍三种聚焦爬虫中的数据解析方式。至此我们的数据爬取的流程可以修改为:
我们之前介绍的是通用爬虫,它用于爬取整张页面信息
聚焦爬虫:聚焦爬虫是建立在通用爬虫的基础之上的,再将我们所需要的数据进行提取(数据解析),从而实现爬取页面中指定的页面内容;
在实现这个我们需求时,先解决一个问题,就是怎样爬取一种图片:
import requests
if __name__ == "__main__":
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.1.2 Safari/605.1.15'}
url = 'https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=3187129139,3162464776&fm=26&gp=0.jpg'
# 使用content返回的是二进制形式的图片数据
img_data = requests.get(url=url).content
with open('./qiutu.jpg', 'wb') as fp:
fp.write(img_data)
import requests
import re
import os
if __name__ == '__main__':
# 创建一个文件夹用于保存所有的图片
if not os.path.exists('./qiutulibs'):
os.mkdir('./qiutulibs')
url = 'http://www.qiushibaike.com/pic/'
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.1.2 Safari/605.1.15'}
# 使用通用爬虫对url对应的一整张页面进行爬取
page_text = requests.get(url=url, headers=headers).text
# 使用聚焦爬虫将页面中所有的糗图进行解析/提取
# 根据网页文本的格式编写正则表达式,提取出图片的url地址
ex = '.*?'
# 获得所有图片url的列表
img_src_list = re.findall(ex, page_text, re.S)
for src in img_src_list:
src = 'https' + src # 拼接一个完整的图片地址
img_data = requests.get(url=src, headers=headers).content
# 生成图片名称
img_name = src.split('/')[-1]
imgPath = 'qiutulips/' + img_name
with open(imgPath, 'wb') as fp:
fp.write(img_data)
from bs4 import BeautifulSoup
if __name__ == '__main__':
# 将本地的html文档中的数据加载到该对象中
fp = open('./text.html', encoding='utf-8')
soup = BeautifulSoup(fp, 'lxml')
print(soup)
from bs4 import BeautifulSoup
if __name__ == '__main__':
# 将本地的html文档中的数据加载到该对象中
page_text = response.text
soup = BeautifulSoup(page_text, 'lxml')
print(soup)
from bs4 import BeautifulSoup
if __name__ == '__main__':
# 将本地的html文档中的数据加载到该对象中
fp = open('./text.html', encoding='utf-8')
soup = BeautifulSoup(fp, 'lxml')
soup.tagName # 返回的是文档中第一次出现的tagName标签
soup.find(tagName, class_=classname) # 第一种用法:返回的是文档中第一次出现的tagName标签
# 第二种用法:属性定位
soup.find_all(tagName, class_=classname) # 第一种用法:返回的是文档中出现的所有tagName标签(列表)
# 第二种用法:属性定位
soup.select('某种选择器(id,class,标签...选择器)') # 返回一个列表
soup.select('.tang > ul > li > a') # 层级选择器,>表示的是一个层级
soup.select('.tang > ul > li a') # 层级选择器,空格表示的是多个层级
# 获取标签之间的文本内容
soup.select('.tang > ul > li a').text # 获取标签中所有的文本内容
soup.select('.tang > ul > li a').string # 只获取该标签下面直系的文本内容
soup.select('.tang > ul > li a').get_text()
# 获取标签中属性值
soup.a['herf']
import requests
from bs4 import BeautifulSoup
if __name__ == '__main__':
# 获取页面数据
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.1.2 Safari/605.1.15'}
url = 'http://www.shicimingju.com/book/sanguoyanyi.html'
page_text = requests.get(url=url, headers=headers).text
# 在首页中解析出章节标题和详情页的url
# 实例话BeautifulSoup对象,需要将页面源码数据加载到该对象中
soup = BeautifulSoup(page_text, 'lxml')
# 解析章节标题和详情页的url
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']
# 对详情页发起请求,解析出章节内容
detail_page_text = requests.get(url=detail_url, headers=headers).text
# 解析出详情也中相关页的内容
detail_soup = BeautifulSoup(detail_page_text, 'lxml')
div_tag = detail_soup.find('div', class_='chapter_content')
# 解析到了章节的内容
content = div_tag.text
fp.write(title + ':\n' + content + '\n')
print(title, '爬取成功!!!')
pip install lxml
# 实例化一个etree对象:
from lxml import etree
etree.parse(filePath)
# 实例化一个etree对象:
from lxml import etree
etree.HTML('page_text')
from lxml import etree
if __name__ == '__main__':
# 实例化了一个etree对象,并将被解析的源码加载到了该对象中
tree = etree.parse('filePath')
# 定位标签相关方法
r = tree.xpath('/html/head/title') # 表示根据层级获取文本内容,返回的是一个对象列表
# 第一个/表示是从根节点开始,往后的每一/表示一个层级
r = tree.xpath('/html//div') # //表示多个层级
r = tree.xpath('//div') # //表示定位所有的div标签内容
r = tree.xpath('//div[@attrName="attrValue"]') # 定位到属性名为song下的所有div标签文本内容(属性定位)
r = tree.xpath('//div[@attrName="attrValue"]/p'[3]) # 索引定位
# 提取标签中的文本
r = tree.xpath('//div[@attrName="attrValue"]//li[5]/a/text()') # /text()方法可以获取标签中的文本(直系的)
r = tree.xpath('//div[@attrName="attrValue"]//li[5]/a//text()')# //text()方法可以获取标签中的文本(所有的)
# 提取属性
r = tree.xpath('//div[@attrName="attrValue"]//img/@attrName')
import requests
from lxml import etree
if __name__ == '__main__':
# 爬取到页面源码数据
headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.1.2 Safari/605.1.15'}
url = 'https://gz.58.com/ershoufang/'
page_text = requests.get(url=url, headers=headers).text
# 数据解析
tree = etree.HTML(page_text)
li_list = tree.xpath('//ul[@class="house-list-wrap"]/li')
# print(li_list)
fp = open('58.txt', 'w', encoding='utf-8')
for li in li_list:
# 页面数据当中局部解析
title = li.xpath('./div[2]/h2/a/text()')[0] # ./表示的就是xpath左侧的li
print(title)
fp.write(title+'\n')
import requests
from lxml import etree
import os
if __name__ == '__main__':
# 爬取到页面源码数据
headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.1.2 Safari/605.1.15'}
url = 'http://pic.netbian.com/4kyingshi/'
response = requests.get(url=url, headers=headers)
# 手动设定编码
# response.encoding = 'utf-8'
page_text = response.text
# 创建etree实例对象
tree = etree.HTML(page_text)
img_src_list = tree.xpath('/html/body/div[@class="wrap clearfix"]/div[@id="main"]/div[@class="slist"]/ul//li')
if not os.path.exists('./tupian'):
os.mkdir('./tupian')
for i in img_src_list:
img_scr = 'http://pic.netbian.com' + i.xpath('./a/img/@src')[0]
img_name = i.xpath('./a/img/@alt')[0] + '.jpg'
# 处理中文乱码较为常用的办法
img_name = img_name.encode('iso-8859-1').decode('gbk')
img_data = requests.get(url=img_scr, headers=headers).content
# 持久化存储
imgPath = 'tupian/' + img_name
with open(imgPath, 'wb') as fp:
fp.write(img_data)
import requests
from lxml import etree
import os
import json
if __name__ == '__main__':
# 爬取到页面源码数据
headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.1.2 Safari/605.1.15'}
url = 'https://www.aqistudy.cn/historydata/'
# 爬取整张页面
page_text = requests.get(url=url, headers=headers).text
# 创建etree实例对象
tree = etree.HTML(page_text)
city_src_list = tree.xpath('/html/body/div[@class="container"]/div[@class="row"]/div[@class="col-lg-9 col-md-8 col-sm-8 col-xs-12"]/div[@class="all"]/div[@class="bottom"]/ul')
fp = open('city_name.txt', 'w', encoding='utf-8')
for i in city_src_list:
city_name = i.xpath('.//li/a//text()')
for j in city_name:
fp.write(j + '、')
fp.write('\n')