python 爬虫 动态网页反爬虫js加密破解思路
前言
最近接了一个单子,需求很简单:爬一个公告目录网站,并且检测公告中是否存在关键词。
听见需求马上就接了,口口声声保证1天以内交单,然而,开始分析网站才发现自己有多么天真。
分析
网站排版很复古,并且用jsp写的,这代表网页是动态生成的,如果直接用requests库发送请求只会获得一些js代码。
打开F12发现有反调试,本人不是专业写爬虫的,对于js解密无能为力,但我也不需要对js解密,有更便捷的方法。
有反调试但不影响我查看元素,简单观察了一下需要爬的元素构造,轻松写出CSS选择器表达式:
标题栏 td[align=‘left’] > span
时间 td[width=‘15%’]
我采用bs4库,方便快捷。
items = soup.select("td[align='left'] > span")
days = soup.select("td[width='15%']")
含标题的元素属性中就有公告正文url,通过url遍历公告正文就可以检测正文中是否含有关键词。
至此项目有了一条明确的思路,接下来解决反爬虫问题。
我们完全没必须去分析那又臭又长的js代码做js解密,完全可以用selenium库模拟浏览器,几乎可以绕过所有反爬虫。
刚开始我首先采用了Edge浏览器驱动,打开网页后发现为空白页,就知道网站做反模拟了。
在查阅资料后,在github上找到一个三方库:undetected_chromedriver,顾名思义反检测谷歌驱动,能够成功绕过网站的反模拟。
该库可以通过 pip install undetected_chromedriver 进行安装
import undetected_chromedriver as uc
options = uc.ChromeOptions()
driver = uc.Chrome(options=options)
def get_html(url, wait_time):
print("正在爬取url:",url)
# 反检测驱动
driver.get(url)
#等待网页加载
time.sleep(wait_time)
html = driver.page_source
#driver.close()
return html
通过以上代码我们就可以获得网站源代码html,传给bs4就能寻找我们需要的元素了。
html = get_html(url + str(page), page_wait_time)
soup = BeautifulSoup(html, "html.parser")
items = soup.select("td[align='left'] > span")
days = soup.select("td[width='15%']")
总结
对于这种js加密+动态网站+反调试的网站,这也算是一个行之有效的思路。