---编码流程:指定Url;发起请求;获取响应数据;数据解析;持久化存储;
数据解析分类:正则;bs4;xpath;
数据解析原理概述:
解析的局部文本内容都会在标签之间或者标签对应属性中进行存储
#需求:爬取图片
import requests
if __name__ == '__main__':
#如何爬取图片数据
url='你想要爬取网页的url'
#content返回的是二进制形式的图片数据
#text(字符串) content(二进制) json() (对象)
img_data=requests.get(url=url).content
with open('./xx.jpg','wb') as fp:
fp.write(img_data)
#需求:糗事百科爬取某个板块下所有的图片
import requests
import re
import os
if __name__ == '__main__':
#创建一个文件夹,保存所有图片
if not os.path.exists('./xxx')
os.mkdir('./xxx')
url='xxxx'
headers={
'User-Agent':xxx
}
#使用通用爬虫对url对应的一整张页面进行爬取
page_text=requests.get(url=url,headers=headers).text
#使用聚焦爬虫将页面中所有糗事图片进行解析/提取
ex='.*?
'
img_src_list=re.findall(ex,page_text,re.S)
for src in img_src_list:
#拼接出完整的图片url
src ='https:'+src
#请求到了图片的二进制数据
img_data=requests.get(url=src,headers=headers).content
#生成图片名称
img_name=src.split('/')[-1]
#图片存储的路径
img_Path='./xxx/'+img_name
with open(img_Path,'wb') as fp:
fp.write(img_data)
print(img_name,'下载成功!!!')
#可以直接爬取下一页的内容
import requests
import re
import os
if __name__ == '__main__':
headers={
'User-Agent':xxx
}
#创建一个文件夹,保存所有图片
if not os.path.exists('./xxx')
os.mkdir('./xxx')
#设置一个通用url模板
url='https://www.qiushibaike.com/pic/page/%d/?s=5184961'
# pageNum=2
for pageNum in range(1,36):
new_url=format(url%pageNum)
#使用通用爬虫对url对应的一整张页面进行爬取
page_text=requests.get(url=new_url,headers=headers).text
#使用聚焦爬虫将页面中所有糗事图片进行解析/提取
ex='.*?
'
img_src_list=re.findall(ex,page_text,re.S)
for src in img_src_list:
#拼接出完整的图片url
src ='https:'+src
#请求到了图片的二进制数据
img_data=requests.get(url=src,headers=headers).content
#生成图片名称
img_name=src.split('/')[-1]
#图片存储的路径
img_Path='./xxx/'+img_name
with open(img_Path,'wb') as fp:
fp.write(img_data)
print(img_name,'下载成功!!!')
1.2 bs4解析
解析原理:
-
标签定位
-
提取标签、标签属性中存储的数据值
- 实例化一个BeautifulSoup对象,并且将页面源码数据加载到该对象中
- 通过调用BeautifulSoup对象中相关的属性或者方法进行标签定位和数据提取
#环境安装
pip install bs4
pip install lxml
对象实例化
# 第一种方法:将本地的html文档中的数据加载到该对象中
fp=open('./test.html','r',encoding='utf-8')
soup=BeautifulSoup(fp,'lxml')
#第二种方法:将互联网获取的页面源码加载到该对象中
page_text=response.text
数据解析的方法和属性
- soup.tagName:返回的是文档中第一次出现的tagName对应的标签
- soup.find():
- find('tagName'):等同于soup.div
- 属性定位:
- soup.find('div',class_/id/attr='song')
- soup.find_all('tagName'):返回符合要求的所有标签(列表)
2.select
select('某种选择器(id,class,标签…选择器)'),返回的是一个列表
soup.select('.tang>ul>li>a'):>表示一个层级
soup.select('.tang>ul a'):空格表示多个层级
获取标签之间的文本数据
soup.a.text/string/get_text()
text/get_text():可以获取某一个标签中所有的文本内容
string:只可以获取该标签下的直系文本内容
获取标签中属性值
soup.a['href']
#需求:爬取三国演义小说的所有章节标题和章节内容
#url:www.shicimingju.com/book/sanguoyanyi.html
import requests
from bs4 import BeautifulSoup
if __name__ == '__main__':
headers={
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36 Edg/95.0.1020.44'
}
url='www.shicimingju.com/book/sanguoyanyi.html'
page_text=requests.get(url=url,headers=headers).text
#在首页中解析出章节标题和详情页的url
#1.实例化BeautifulSoup对象,将页面源码加载到该对象中
soup=BeautifulSoup(page_text,'lxml')
#解析章节标题和详情页的url
li_list=soup.select('.book-mulu>ul>li')
fp=open('./sanguo.csv','w',encoding='utf-8')
for li in li_list:
title=li.a.string
detail_url='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_context')
#解析到章节的内容
content=div_tag.text
fp.write(title':'+content+'\n')
print(title)
1.3xpath
最常用且最便捷的一种解析方式。通用性
解析原理:
- 实例化一个etree的对象,且需要将被解析的页面源码数据加载到该对象中。
- 调用etree对象中的xpath方法结合着xpath表达式实现标签的定位和内容的捕获
环境安装:
pip install lxml
如何实例化:
- 将本地html文档中的源码数据加载到etree对象中:etree.parse(filePath)
- 可以将从互联网上获取的源码数据加载到该对象中:etree.HTML('page_text')
xpath(‘xpath表达式’)
#本地化
from lxml import etree
if __name__ == '__main__':
#实例化好了一个etree对象,且将被解析
tree=etree.parse('test.html')
r=tree.xpath('/html/head/title')
print(r)
xpath表达式:
- /:表示 的是从根节点开始定位,表示一个层级。
- //:表示多个层级,可以表示从任意位置开始定位。
- 属性定位://div[@class='song'] tag[@attrName="attrValue"]
- 索引定位://div[@class="song"]/p[3] 索引是从1开始的。
取文本:
- /text():获取的是标签中直系的文本内容
- //text():标签中非直系的文本内容(所有的文本内容)
取属性:
- /@attrName ==>img/src
案例
#需求:爬取58二手房的信息
import requests
from lxml import etree
if __name__ == '__main__':
headers={
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36 Edg/95.0.1020.44'
}
#爬取到页面源码数据
url='https://bj.58.com/ershoufang/'
page_text=requests.get(url=url,headers=headers).text
#数据解析
tree=etree.HTML(page_text)
li_list=tree.xpath('//ul[@class="houser-list-wrap"]/li')
fp=open('58.csv','w',encoding='utf-8')
for li in li_list:
#局部解析
title=li.xpath('./div[2]/h2/a/text()')[0]
print(title)
fp.write(title+'\n')
#需求:解析下载图片数据
import requests
from lxml import etree
import os
if __name__ == '__main__':
headers={
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36 Edg/95.0.1020.44'
}
#爬取到页面源码数据
url='https://pic.netbian.com/4kmeinv/'
response=requests.get(url=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]')
#创建一个文件夹
if not os.path.exists('./picLibs'):
os.mkdir('./picLibs')
for li in li_list:
img_src='https://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')
print(img_name,img_src)
#请求图片进行持久化存储
img_data=requests.get(url=img_src,headers=headers).content
img_path='./picLibs/'+img_name
with open(img_path,'wb') as fp:
fp.write(img_data)
print(img_name,'下载成功!!!')
#需求:爬取全国城市名称
import requests
from lxml import etree
import os
if __name__ == '__main__':
headers={
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36 Edg/95.0.1020.44'
}
url='https://www.aqistudy.cn/historydata/'
page_text=requests.get(url=url,headers=headers).text
tree=etree.HTML(page_text)
host_li_list=tree.xpath('//div[@class="bottom"]/ul/li')
all_city_names=[]
#解析到了热门城市的城市名称
for li in host_li_list:
hot_city_name=li.xpath('./a/text()')[0]
all_city_names.append(hot_city_name)
#解析的是全部城市的名称
city_names_list=tree.xpath('//div[@class="bottom"]/ul/div[2]/li')
for li in city_names_list:
city_names=li.xpath('./a/text()')[0]
all_city_names.append(city_names)
print(all_city_names,len(all_city_names))
#div[@class="bottom"]/ul/li/ 热门城市a标签的层级关系
# div[@class="bottom"]/ul/div[2]/li/a 全部城市a标签的层级关系
课程资源来源于网络 ,文章均为原创,如转载请注明出处!!!