CSS位置偏移反爬案例分析与实战
1. 案例分析
上一节学习了Selenium这个自动化测试工具,但这个工具不是万能的,不容易爬取的数据依然存在,例如网页利用CSS控制文字的偏移位置,或者通过一些特殊的方式隐藏关键信息,这都会对数据爬取造成干扰。可以看这一部分代码:
from selenium import webdriver
from pyquery import PyQuery as pq
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
browser = webdriver.Chrome()
browser.get('https://antispider3.scrape.center/')
WebDriverWait(browser, 10) \
.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, '.item')))
html = browser.page_source
doc = pq(html)
names = doc('.item .name')
for name in names.items():
print(name.text())
Wonder
清 白 风 家
法 老 的 宠 妃 终 结 篇 ( 上 下 册 )
( ) 二 己 为 士 知 册 全
年 一 孩 追 些 们 那 女 起 的 我 ,
全 ( 册 三 城 倾 我 ) 非
明 朝 儿 那 事 些
以上是这一段代码的部分输出结果,可以看出来,大部分书名都是乱序的,这是因为网页使用了CSS位置偏移,一下是“清白家风”这一本书的书名部分的代码:
<h3 data-v-7f1a77ef="" class="m-b-sm name"><span data-v-7f1a77ef="" class="char" style="left: 0px;">
清
</span><span data-v-7f1a77ef="" class="char" style="left: 16px;">
白
</span><span data-v-7f1a77ef="" class="char" style="left: 48px;">
风
</span><span data-v-7f1a77ef="" class="char" style="left: 32px;">
家
</span></h3>
我们可以看到span中的style属性,表示CSS样式,left的取值各不相同,并且我们在查看span节点的完整样式时候,可以看到:
.item .bottom .name .char[data-v-7f1a77ef] {
display: inline-block;
position: absolute;
}
以上是span节点的两个额外样式,是display和position,而后者表示绝对定位,设置这个样式之后,就可以通过left样式控制span节点在页面中的偏移位置了。了解了为什么会出现这样的情况之后,我们就可以直接通过这个偏移位置来重新安排一下文字的顺序。
这里穿插一些题外话:span节点里面的文本有格式,而pyquery可以省略这些格式,使用get_attribute()或者text就不行了,所以建议复习一下puquery。以下是一个span节点,可以看出格式问题:文章来源:https://www.toymoban.com/news/detail-703161.html
<span data-v-7f1a77ef="" class="char" style="left: 0px;">
清
</span>
2.爬取实战
思路:利用正则表达式将偏移量提取出来,接着根据偏移量对字体进行排序处理。文章来源地址https://www.toymoban.com/news/detail-703161.html
from selenium import webdriver
from pyquery import PyQuery as pq
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
import re
def parse_name(name_html):
has_whole = name_html('.whole')
if has_whole:
return name_html.text()
else:
chars = name_html('.char')
items = []
for char in chars.items():
items.append({
'text': char.text().strip(),
'left': int(re.search('(\d+)px', char.attr('style')).group(1))
})
items = sorted(items, key=lambda x: x['left'], reverse=False)
return ''.join([item.get('text') for item in items])
browser = webdriver.Chrome()
browser.get('https://antispider3.scrape.center/')
WebDriverWait(browser, 10) \
.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, '.item')))
html = browser.page_source
doc = pq(html)
names = doc('.item .name')
for name_html in names.items():
name = parse_name(name_html)
print(name)
browser.close()
到了这里,关于【爬虫】7.3. CSS位置偏移反爬案例分析与实战的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!