打开Python爬虫实战练习页面CSS伪元素反爬_N04_Spiderbuf,可以看到页面内容是豆瓣电影评分。
在网页上点击右键 > 显示网页源代码,可以看到网页结构也并不复杂。往下滚动查看源码,第115行开始是豆瓣电影内容介绍及评分。
第115行HTML源码找到了9.3这样的数字,看起来是电影评分,但回到页面上看,实际上看到的是9.7这样的内容。很明显HTML源码里的内容是用来误导爬虫的。
<span>豆瓣电影评分:</span><span class="mnopqr pkenmc">.</span><span class="rbmsak">9.3</span><br />
从源码来看,有一个 rbmsak 这样的CSS类包裹了起来,我们就搜索 rbmsak 找到这个样式。在源码第442行找到了这个样式的定义代码,发现它只是定义了一个字体颜色。
.rbmsak {
color: #141d2b;
}
回到页面内容,通过浏览器开发者工具(F12)选中元素的功能选中第一个电影信息的豆瓣评分这里,就能发现这个rbmsak 样式把9.3这个值通过设置成网页背景颜色的方式隐藏了,也就是说我们在网页上看到的真实的值不是这个。但是我们在开发者工具 -> 元素这里能看来如下的代码:
注意其中的 before 及 after 代码,结合CSS相关知识可知,这里是由CSS进行了赋值。通常关键字搜索上面代码中出现的类名 mnopqr ,找到以下CSS样式代码:
.mnopqr::before {
content: "9";
}
.mnopqr::after {
content: "1";
}
这里明显就是CSS赋值到html的代码,而且可以发现这样的定义代码还有一长串。CSS before 及 after 是把 content 里面的内容赋值到html里面的,换句话来说,我们只要从html中取到类名,并找出对应类名中的 content 的内容就可以把真实的内容爬取下来。根据这个思路,我们先用Python代码构造一下字典:
class_map = {'abcdef::before':'7',
'abcdef::after':'5',
'ghijkl::before':'8',
'ghijkl::after':'9',
'mnopqr::before':'9',
'mnopqr::after':'1',
'uvwxyz::before':'1',
'uvwxyz::after':'4',
'yzabcd::before':'2',
'yzabcd::after':'6',
'efghij::before':'3',
'efghij::after':'2',
'klmnop::before':'5',
'klmnop::after':'7',
'qrstuv::before':'4',
'qrstuv::after':'3',
'wxyzab::before':'6',
'wxyzab::after':'0',
'cdefgh::before':'0',
'cdefgh::after':'8',
'hijklm::after':'6',
'opqrst::after':'0',
'uvwxab::after':'3',
'cdijkl::after':'8',
'pqrmno::after':'1',
'stuvwx::after':'4',
'pkenmc::after':'7',
'tcwdsk::after':'9',
'mkrtyu::after':'5',
'umdrtk::after':'2'}
字典的键是完整的CSS类名,字典的值是CSS类定义代码中 content 中的内容,我们就可以通过类名转换获取到对应的值。
attr_class = span.attrib['class'] if 'class' in span.attrib else ''
classes = attr_class.split(' ')
if len(classes) > 0:
s1 = class_map[classes[0] + '::before']
s2 = class_map[classes[1] + '::after']
print(f'{s1}.{s2}')
这样我们就完成了豆瓣电影评分值的爬取。
至于页面中的其它内容,没有特别的反爬措施,只需要获取到对应的xpath表达式然后提取内容即可。
完整示例代码:示例代码