我们在用python解析网页的时候,会用到各种各样的库,比如BeautifulSoup、xpath等,这些库能帮我们达到解析网页、提取数据的目的,但是提取效率比较低、而且代码量较大,所以今天来介绍一个HTML解析神器 —— CSS选择器。
网页结构
掌握CSS选择器之前,我们首先要了解网页的基本结构。
This is titleThis is body
这是一个网页最基本的结构,其中是最大一级的标签,称为“根标签”,
是网页文档的头部,是网页文档的标题,它属于的子标签【位于的下一级并缩进一个tab】,是网页文档的主体,其属于的同级标签【与位于同一级】【注意点】区分两个标签是父子标签或同级标签最好的办法是看他们是否上下对齐,上下对齐的便是同级标签;如果一个标签位于另一个标签下,并且缩进了一个tab(4个空格),那么这两个标签便是父子标签。
CSS选择器
了解完最基本的网页结构后,我们正式开始介绍今天的主角--CSS选择器,CSS选择器是一种模式,用于选择需要添加样式的元素。使用的最多的是6种选择器,分别是标签选择器,类选择器,ID选择器,伪类选择器,组合选择器,属性提取器,下面就开始逐个介绍他们。
【本喵习惯使用parsel库将html转换成selector对象后使用css选择器提取,因此下文的代码都是基于parsel库】
01-标签选择器
标签选择器其实就是通过选择标签来提取需要的元素,比如html、p、div等,都是标签,比如我们想要选择title标签,那么我们可以编写如下代码
import parsel
html =
'''
This is titleThis is body
'''
selector = parsel.Selector(html) //把html转换成selector对象
title = selector.css("title") //使用css选择器选取title标签
print(title.getall()) // getall()方法将selector对象转换成字符串
02-类选择器
类选择器就是通过选取标签中的class元素样式效果来快速定位所在的标签,类选择器是最常用的,但是要注意,通过类选择器选取的标签可能不唯一。
使用方法:使用". + class属性"【一个点+class】即可选取class所在的标签。
比如,我们需要选取class="grid_view"所在的标签,只需要使用".grid_view"即可选取,代码如下:
import parsel
selector = parsel.Selector(html) //把html转换成selector对象
class_grid = selector.css(".grid_view") //使用类选择器选取grid_view标签
print(class_grid.getall()) // getall()方法将selector对象转换成字符串
03-ID选择器
ID选择器通过id标签来快速定位,与类选择器相比,使用ID选择器提取的值是唯一的,因为网页上各个id值是唯一的,因此如果标签含有id属性,优先使用ID选择器。
使用方法:使用"# + id标签的值"即可提取id值所在的标签
比如:我们需要提取id = "content"所在的标签,可以使用"#content"来提取,代码如下:
import parsel
selector = parsel.Selector(html) //把html转换成selector对象
content = selector.css("#content") //使用类选择器选取grid_view标签
print(content.getall()) // getall()方法将selector对象转换成字符串
04-伪类选择器
通过伪类选择器,我们可以选择同级标签下的任意标签,通过:指定选择标签的属性。用的最多的是first-child;last-child;nth-child(n)。
1. first-child 指选取同级标签中的第一个标签
2. last-child指选取同级标签中的最后一个标签
3. nth-child(n) 指选取同级标签中的第n个标签
使用方法:选取同级标签时后方加上伪类选择器即可,如 "li:first-child"
import parsel
selector = parsel.Selector(html) //把html转换成selector对象
li = selector.css(".grid_view li:nth-child(3)") //使用伪类选择器选取第三个li标签
print(li.getall()) // getall()方法将selector对象转换成字符串
05-组合选择器
组合选择器是指标签选择器、类选择器、id选择器可以混合着使用,各个标签之间使用空格隔开,如果需要限定在子标签,则使用">"连接。
06-属性提取器
属性提取器用于提取标签内的属性,比如href,src等属性。
使用方法为:标签后 +":attr(属性名)",比如".pic a ::attr(href)"
import parsel
selector = parsel.Selector(html) //把html转换成selector对象
li = selector.css(".pic a::attr(href)") //使用属性提取器提取href属性
print(li.getall()) // getall()方法将selector对象转换成字符串
掌握以上概念后,基本就可以轻松驾驭CSS选择器了,不过当然也少不了刻意训练。下面附上CSS选择器提取豆瓣250数据的爬虫案例,小伙伴可以拿来练练手。相信我,你一定会喜欢上用CSS选择器滴。
import requests
import parsel
class douban_crawler():
def __init__(self):
self.headers ={
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36}",
}
self.url = "https://movie.douban.com/top250"
def main(self):
'''主函数'''
for i in range(0,10):
params = {
'start': i*25,
'filter': '',
}
self.get_data(self.url,params)
print("爬取完成")
def get_data(self,url,params):
response = requests.get(url,headers = self.headers,params=params,allow_redirects=False)
selector = parsel.Selector(response.text)
lis = selector.css(".grid_view li")
''' 使用css解析提取数据'''
for li in lis:
title = li.css(".info div a .title::text").getall()
title = "".join(title)
info = li.css(".bd p::text").getall()
info = self.clean_data(info)
score = li.css(".rating_num::text").get()
follow = li.css(".star span:nth-child(4)").get()
data = "{},{},{},{}\n".format(title,info,score,follow)
print(data)
self.save_data(data)
def clean_data(self,data):
list = []
for i in data:
i = i.strip()
list.append(i)
text = " ".join(list)
return text
def save_data(self,data):
with open("douban250.txt",mode="a",newline="",encoding="utf-8") as f:
f.write(data)
if __name__ == '__main__':
crawler = douban_crawler()
crawler.main()
作者:爱学习,也爱女票的于饼喵