「这是我参与2022首次更文挑战的第25天,活动详情查看:2022首次更文挑战」
今天主要讲解使用request库爬取网页原始数据,然后使用三种方式,正则表达式、bs4、xpath进行数据的定位和解析。爬取数据库然重要,但学会了如何处理网页数据也是重中之重。
数据解析概述
- 解析的局部的文本内容都会在标签之间或者标签对应的属性中进行存储
- 1.进行指定标签的定位
- 2.标签或者标签对应的属性中存储的数据值进行提取(解析)
正则表达式
常用正则表达式
html_url = 'https://tieba.baidu.com/f?kw=%E7%99%BE%E5%BA%A6%E7%99%BE%E7%A7%91&ie=utf-8&tab=album'
user_headers = {
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36 SLBrowser/7.0.0.12151 SLBChan/30"
}
parms = {
"kw": "百度百科",
"ie": "utf-8",
"tab": "album"
}
response = requests.get(url=html_url, params=parms, headers=user_headers).text
#with open("./111.html","w",encoding="utf-8") as fp:
# fp.write(response)
# 使用正则表达式获取页面中的图片
ex = '<img src="(.*?)"'
img_src_list = re.findall(ex,response,re.S)
print(img_src_list)
bs4解析数据
bs4数据解析的原理
-
1.实例化一个BeautifulSoup对象,并且将页面源码数据加载到该对象中
-
2.通过调用BeautifulSoup对象中相关的属性或者方法进行标签定位和数据提取
环境安装:
-
pip install bs4- -
pip install lxml
如何实例化BeautifulSoup对象:
from bs4 import BeautifulSoup
对象的实例化:
-
1.将本地的html文档中的数据加载到该对象中
fp = open( './test.html' ,'r',encoding='utf-8') soup =BeautifulSoup( fp, 'lxml') -
2.将互联网上获取的页面源码加载到该对象中
text = response.text soup = BeautifulSoup(text,'lxml')
相关解析数据的方法和属性
-
soup.tagName:返回的是文档中第一次出现的tagName对应的标签-
-
soup.find():
-
find( 'tagName' ):等同于soup.div -
属性定位
soup.find( 'div' ,class_/id/attr= ' song ')
-
-
soup.find all( 'tagName '):返回符合要求的所有标签(列表)
select:
-
select('某种选择器(id,class,标签...选择器)'),返回的是一个列表。
层级选择器:
-
soup.select( '.tang > ul > li > a '):>表示的是一个层级
-
oup.select( '.tang > ul a'):空格表示的多个层级
注意:常用的选择器有三种,标签选择器,类选择器,id选择器。标签选择器前面什么都不加;使用类选择器——'.类名';id选择器——'#id'
获取文本内容/属性值
·获取标签之间的文本数据:
-
soup.a.text/string/get text()
-
text/get_text():可以获取某一个标签中所有的文本内容
-
string:只可以获取该标签下面直系的文本内容
获取标签中属性值:
- soup.a[ ' href' ]
xpath解析数据
xpath解析原理:
1.实例化一个etree的对象,且需要将被解析的页面源码数据加载到该对象中。 2.调用et ree对象中的xpath方法结合着xpath表达式实现标签的定位和内容的捕获。
环境的安装:
pip install lxml
如何实例化一个etree对象:
先导入from lxmL import etreel
1.将本地的html文档中的源码数据加载到etree对象中:
etree.parse(filePath )
2.可以将从互联网上获取的源码数据加载到该对象中
etree.HTML( ' page_ text ' )
相应的语法
xpath表达式:
-
/表示的是从根节点开始定位。表示的是一个层级。
-
//:表示的是多个层级。可以表示从任意位置开始定位。
-
属性定位: //divl@class='song' ] tag [@attrName="attrValue"]
-
索引定位: //div[@class="song"]/p[3] 索引是从1开始的。 取文本:
-
/text()获取的是标签中直系的文本内容
-
//text()标签中非直系的文本内容(所有的文本内容)
取属性: /@attrName -------->img/@src 表示定位到img标签取得是其中的src属性
注意:
1、/表示是从根节点开始定位(html),如果是局部标签的下级使用./
2、xpath返回的永远是列表,如果要使用其中的元素可以使用下标访问法
xpath实战
需求:爬取高清4k图片
# 确定网页的url
html_url = 'https://pic.netbian.com/4kmeishi/'
# 进行UA伪装
user_header = {
"user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.80 Safari/537.36 Edg/98.0.1108.43"
}
# 发起请求获取响应对象
response = requests.get(url=html_url,headers=user_header)
response.encoding = "gbk"
html_text = response.text
# 构造etree对象
tree = etree.HTML(html_text)
li_list = tree.xpath("//ul[@class='clearfix']/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]
# 再次发起请求获取图片二进制数据
img_data = requests.get(url=img_src, headers=user_header).content
# 持久化数据
img_path = "picLibs/" + img_name + ".jpg"
#print(img_src,img_name)
with open(img_path,"wb") as fp:
fp.write(img_data)
print(img_name+"打印成功!")