哈喽大家好,我是鹏哥。
今天继续上周的主题是 —— boss直聘网站的爬虫。
~~~上课铃~~~
盗墓笔记·十年人间李常超(Lao乾妈) - 盗墓笔记·十年人间
1
写在前面
上一篇文章讲的如何破解boss直聘网站的滑块认证:
这个方法对优快云、淘宝等网站都是有效的。后来看到有人留言说,为什么不用cookies?这样就直接避免了账号密码认证。嗯,说的有道理。因此我在补充这第2弹时,也补充下cookies保存、加载的说明。
当然重点还是记录下我在爬虫boss网站时,遇到的几类selenium找不到元素的原因及对应的规避方法。
2
cookies免账号验证
cookies信息的获取,在selenium库中有现成的方法可以调用:driver.get_cookies();而加载网页时,只需要再调用driver.add_cookie()即可。具体代码实现可以参考以下示例代码:
# coding=utf-8
# @公众号 : "鹏哥贼优秀"
# @Date : 2020/3/29
# @Software : PyCharm
# @Python version: Python 3.7.2
from selenium import webdriver
import json
import time
class Cookies:
def __init__(self, driver):
self.driver = driver
def save_cookies(self):
cookies = self.driver.get_cookies()
json_cookies = json.dumps(cookies)
# 保存cookies,方便后续加载使用
with open('cookies.json', 'w', encoding='utf-8') as f:
f.write(json_cookies)
def add_cookies(self):
# 加载前先清除之前的cooikes,防止影响
self.driver.delete_all_cookies()
with open('cookies.json', 'r', encoding='utf-8') as f:
list_cookies = json.loads(f.read())
for i in list_cookies:
self.driver.add_cookie(i)
if __name__ == "__main__":
url = 'https://www.zhipin.com/job_detail/?ka=header-job'
option = webdriver.ChromeOptions()
option.add_experimental_option('excludeSwitches', ['enable-automation'])
driver = webdriver.Chrome('chromedriver.exe',options=option)
driver.maximize_window()
driver.get(url)
time.sleep(3)
cookies = Cookies(driver)
# # 保存cookies
# cookies.save_cookies()
# 加载cookies
cookies.add_cookies()
driver.get(url)
time.sleep(3)
整体代码还 是比较简单易理解的,与之前selenium使用的区别仅在于:打开网页后再重新加载cookies并刷新,这样就实现了cookies免账号认证的功能。
3
常见selenium找不到元素的情况
下面我就汇总下几类常见selenium找不到元素的情况,及对应的解决方法。
情况1:find_element_by_XX()方法使用不正确
selenium最简单的元素查找方法是通过id、name、class_name:
driver.find_element_by_class_name()
driver.find_element_by_name()
driver.find_element_by_id()
只要网页上有明确的这三个字段,基本不会找错。但是很多时候网页元素并不能通过以上方法实现,如<div class="info primary">类class_name中有空格即需要其他方法来查找了;又如下方这个元素即没 id,也没class_name,就不好找了。
<a href="/gongsi/dbc073226b21d2830Hx93d67.html" title="涂鸦智能招聘" ka="search_list_company_2_custompage" target="_blank">涂鸦智能</a>
因此我就想到了万能的元素查找方法:driver.find_element_by_xpath()但是由于自己对html不熟悉,经常出现找不到元素。这里教大家一个小技巧:通过F12的查找,将你自己的xpath代码输入进行查找。
如上图,可以在查找对话框中将自己的xpath输入,如果是正确的话就能找到自己的相应元素。通过这个小技巧可以快速避免自己的代码。
如果说第1种情况是由于自己代码功底不足,那接下去的几类情况就是网站反爬虫导致的。
情况2:网页元素设置成不可见
一般我们通过selenium打开网站后,自己是能看到想要的内容,但是代码却一直报找不到元素,如下图:
我要找这个“项目经理”元素,却就是找不到。这 里我们要仔细看下html代码了。看到没?网站设置了当前界面为style='display:none',就是这个style导致了selenium找不到。
作为常见的反爬虫方法,解决方法也很简单,只需要将style设置为可见即可,规避方法如下:
js = "document.getElementsByClassName('job-tab')[0].style.display='block';"
driver.execute_script(js)
情况3:iframe内嵌表单切换
有时候即使你已经设置了style可见,发现还是找不到元素,这是为什么?先别急,我们再仔细看看html代码。
看到没?你会发现你要找的元素在一个新的iframe。怎么理解呢?相当于你开始进入的是房子的大门,但是你要的元素却是在房子里的一个小房间里,所以你要走进这个小房间。
规避方法:找到对应iframe元素,然后switch_to.frame
driver.switch_to.frame(driver.find_element_by_name('zhipinFrame'))
如果最后要切换之前的iframe,可以用switch_to.default_content()跳回最外层的页面
一般来说,论文留言板块都会采用iframe内嵌表单,所以可以关注下。
情况4:网页元素未加载完成
我一开始在爬虫Boss时,发现一样的driver.find_element_by_xpath('ul[{}]'.format(i))时,有时候能找到元素,有时候却报错,提示找不到元素。
最后从我自己的试验来看,应该是用xpath查找时,对应元素还未加载完成,导致偶现的找不到元素。
规避方法:time.sleep(3)。
这里我说下,有些博客里说只要等0.5S或者 1S就够了,但是boss时间不够的,sleep(1)仍然会出现找 不到的现象。
情况5:界面元素加载属于懒加载
很多网站在显示内容时,采用了懒加载,如boss显示牛人信息时,滑到底部需要等一下才会加载出新的内容。但是如果用selenium打开网站,能爬取的元素只有当前展示内容,因此需要模拟用户进行滚轮滑动。
js = 'var action=document.documentElement.scrollTop=50000'
driver.execute_script(js)
这个滚轮加载的动作可以在查找元素前做,这样第一次查找时就可以爬取到更多内容。(可以写个循环即可以多滚动几页了)
情况6:能找到对应元素,却无法点击
上面讲到了滚轮加载更多的元素,但是也会出现一个情况。如 我要点击“立即沟通”这个按钮,我能通过find_element_by_xx找到,但是报没此元素因此点击不了。
这里是因为当前界面中的确无此元素,而是当前界面的前几页。
规避方法:
这里我采用的是循环向上翻页,并在每页尝试查找此元素。
for i in range(5):
try:
# 查找此元素并点击
driver.find_element_by_name('test').click()
except:
# 向上翻页
js = 'var action=document.documentElement.scrollTop=0'
driver.execute_script(js)
continue
5
总结
目前我自己遇到的找不到元素大致是这些情况,希望能帮助大家跳坑。
~~~下课铃~~~
【往期热门文章】:
【Python成长之路】10行代码教你免费观看无广告版的《庆余年》腾讯视频
【Python成长之路】如何用python开发自己的iphone应用程序,并添加至siri指令
【Python成长之路】从 零做网站开发 -- 基于Flask和JQuery,实现表格管理平台
点击下方诗句,可以留言互动喔
【关注“鹏哥贼优秀”公众号,回复“python学习材料”,将会有python基础学习、机器学习、数据挖掘、高级编程教程等100G视频资料,及100+份python相关电子书免费赠送!】
扫描二维码
与鹏哥一起
学python吧!