【Python成长之路】破解Boss直聘网站滑块验证

 

哈喽大家好,我是鹏哥。

 

今天要记录的内容是 —— 破解Boss直聘网站的滑块验证。

 

 

…… 上 课 铃……

TuesdayBurak Yeter;Danelle Sandoval - Tuesday

1

写在前面

最近领导安排我投入公司招聘工作,然后自然就需要不停地在boss直聘网上进行人才搜索。搞了几天我就觉得无趣又繁琐,那就干脆爬虫下吧。由于boss直聘网站的网页设计代码写的比较好,获取元素也很方便,因此不到十分钟就写完了界面登录的selenium代码。原以为很简单的滑块验证,却让我烦恼了好久!

下面让我一步步来讲下我遇到的坑以及相应的解决方法

2

跳坑过程

# coding=utf-8# @公众号 : "鹏哥贼优秀"# @Date : 2020/3/20# @Software : PyCharm # @Python version: Python 3.7.2from selenium import webdriverfrom slide_solution import *import time
def visit_website(url):    driver = webdriver.Chrome('F:\\Python成长之路\\chromedriver.exe')    driver.maximize_window()    driver.get(url)    time.sleep(1)    # 输入帐户密码    driver.find_element_by_name('account').send_keys('手机号')    driver.find_element_by_name('password').send_keys('password')    slide_btn = driver.find_element_by_css_selector('span[class="nc_iconfont btn_slide"]')    # 滑块解决方法1    slide_solution1(slide_btn,driver)
    time.sleep(1)    driver.find_element_by_class_name('btn').click()    time.sleep(5)    driver.quit()
if __name__ == "__main__":    url = 'https://login.zhipin.com/?ka=header-login'    visit_website(url)

    这是登录boss的主要代码,其中滑块验证的代码我是这么写的:​​​​​​

def slide_solution1(slide_btn,driver):    action = ActionChains(driver)    action.click_and_hold(slide_btn).perform()    for i in range(200):        try:            action.move_by_offset(i*2,0).perform()        except:            break        action.reset_actions()        time.sleep(0.1)

        我按每0.1移动2个像素的速度,将滑块从最左边移到右边,从现象来看效果也是可以的,滑块的确移过去了。(其实也可以不用慢慢移动,可以直接action.move_by_offset(276,0).perform()来直接实现,276是滑块验证的像素长度)。

但是坑来了!

代码移动滑块后,界面报错如下:

尝试解决方法1:

一开始针对这种问题,网上资料是比较多的,我很快就知道了,是因为网页的window.navigator.webdrive字段设置为true。从大神们的博客中了解到,相当于网站通过这个字段可以知道chrome是人为打开,还是代码启动的。因此,相应的解决方法很快出来了。​​​​​​​

# 配置window.navigator.webdrive    option = webdriver.ChromeOptions()    option.add_experimental_option('excludeSwitches', ['enable-automation'])    driver = webdriver.Chrome('F:\\Python成长之路\\\滑块问题\\chromedriver.exe',options=option)

在启动chrome时,添加option,即停用开发者模式,这样就可以解决window.navigator.webdrive问题了,如下图所示。

尝试解决2:

很快我再次重试滑块时,发现仍然报一样的错误。这时候,网上的资料基本就不多了,对我的帮助也比较少。我猜测,可能是 ActionChains库的问题,有可能被网站检测到了。因此我想到了sikuli jar包。这个方法几乎可以实现任何的界面自动化,想了解的同学可以参考:

【Python成长之路】基于sikuli jar包,实现淘宝自动抢单功能(1)

这里相应的滑块移动代码如下:​​​​​​​

def slide_solution2():    jvmPath = jpype.get_default_jvm_path()    # Djava.class.path是本地的sikuliapi.jar包路径,需要提前下载好    jpype.startJVM(jvmPath, '-ea', '-Djava.class.path=F:\\sikuli\\1\\sikulixapi.jar')    Screen = JClass('org.sikuli.script.Screen')    myscreen = Screen()    myscreen.drag('start.PNG','end.PNG')    time.sleep(0.5)

    对应的图片如下:

end.png

       start.png

因为从我的理解来看,用sikuli库相当于就是人为操作鼠标进行移动。结果很不幸,还是一样的报错!我去!这也不行?

然后我在打开的chrome界面,手动滑动滑块,发现也是报错。这时候,我觉得可能是chrome启动时就以为被判定为非人为操作,因此无论后面仍然的操作,都会失败!

3

滑块验证最终解决方法

看到一篇大神的文章《python selenium滑动验证防检测》(http://www.py3study.com/Article/details/id/19698.html),作者将chromedriver.exe文件进行了反编译并修改。竟然还有这种操作!

(1)下载wxMEdit工具,并打开chromedriver.exe;

(2)将key值 中$cdc改名,如下,改成$abc

(3)保存新的chromedriver.exe文件

(4)将代码中的chromedriver.exe替换成修改后的exe

成功了!

4

滑块验证的另一种解决方法

在查找资料时,发现有大神说,如果用firefox浏览器代替chrome,相同的代码可以直接成功!这个方法我就没去尝试了,需要下载特定的旧版本firefox,以及下载对应的驱动文件。不过网上关于firefox安装selenium插件的资料还是挺多的。

5

总结

在查找滑块解决方法时,很多同学都遇到了相同的问题,为了后续方便其他人跳坑 ,因此想到写些博客,方便后来的同学吧!

如果有同学需要,可以访问以下网站获取代码及修改后的chromedriver.exe:https://github.com/yuzipeng05/slide_solution.git

 

…… 下 课 铃……

 

【往期热门文章】:

【Python成长之路】10行代码教你免费观看无广告版的《庆余年》腾讯视频

【Python成长之路】如何用python开发自己的iphone应用程序,并添加至siri指令

【Python成长之路】从 零做网站开发 -- 基于Flask和JQuery,实现表格管理平台

点击下方诗句,可以留言互动喔  

你对的人,正在马不停蹄,披星戴月,风雨兼程,你在等等。

 

【关注“鹏哥贼优秀”公众号,回复“python学习材料”,将会有python基础学习、机器学习、数据挖掘、高级编程教程等100G视频资料,及100+份python相关电子书免费赠送!】

 

扫描二维码

    与鹏哥一起

学python吧!

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是使用Python爬取BOSS直聘岗位数据并进行可视化的步骤: 1. 导入必要的库 ```python import requests from bs4 import BeautifulSoup import pymysql from pyecharts.charts import Bar, Pie, WordCloud from pyecharts import options as opts from flask import Flask, render_template ``` 2. 爬取数据 ```python # 爬取BOSS直聘网站上的数据 def get_data(url): headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'} response = requests.get(url, headers=headers) soup = BeautifulSoup(response.text, 'html.parser') return soup ``` 3. 爬取多页数据 ```python # 爬取多页数据 def get_all_data(): all_data = [] for i in range(1, 11): url = 'https://www.zhipin.com/c101280100-p100109/?page={}&ka=page-{}'.format(i, i) soup = get_data(url) data_list = soup.find_all('div', class_='job-primary') for data in data_list: job_name = data.find('div', class_='job-title').text.strip() salary = data.find('span', class_='red').text.strip() company = data.find('div', class_='company-text').find('a').text.strip() education = data.find('div', class_='job-limit clearfix').find_all('span')[1].text.strip() welfare = data.find('div', class_='info-append').find_all('span') welfare_list = [w.text.strip() for w in welfare] all_data.append([job_name, salary, company, education, welfare_list]) return all_data ``` 4. 存储数据 ```python # 存储数据到MySQL数据库 def save_data(data): db = pymysql.connect(host='localhost', user='root', password='123456', port=3306, db='boss_zhipin') cursor = db.cursor() sql = 'INSERT INTO job_info(job_name, salary, company, education, welfare) values(%s, %s, %s, %s, %s)' try: cursor.executemany(sql, data) db.commit() except Exception as e: print(e) db.rollback() db.close() ``` 5. 数据可视化 ```python # 数据可视化 app = Flask(__name__) @app.route('/') def index(): return render_template('index.html') @app.route('/salary') def salary(): db = pymysql.connect(host='localhost', user='root', password='123456', port=3306, db='boss_zhipin') cursor = db.cursor() sql = 'SELECT salary FROM job_info' cursor.execute(sql) results = cursor.fetchall() salary_list = [] for result in results: salary = result[0].replace('k', '').replace('K', '') salary_list.append(int(salary)) salary_dict = {} for i in range(0, 31, 5): salary_dict['{}k-{}k'.format(i, i + 5)] = 0 for salary in salary_list: for key in salary_dict.keys(): if salary >= int(key.split('-')[0]) and salary <= int(key.split('-')[1]): salary_dict[key] += 1 bar = Bar() bar.add_xaxis(list(salary_dict.keys())) bar.add_yaxis('薪资分布', list(salary_dict.values())) bar.set_global_opts(title_opts=opts.TitleOpts(title='BOSS直聘薪资分布图')) return bar.dump_options_with_quotes() @app.route('/education') def education(): db = pymysql.connect(host='localhost', user='root', password='123456', port=3306, db='boss_zhipin') cursor = db.cursor() sql = 'SELECT education FROM job_info' cursor.execute(sql) results = cursor.fetchall() education_list = [] for result in results: education_list.append(result[0]) education_dict = {} for education in education_list: if education in education_dict.keys(): education_dict[education] += 1 else: education_dict[education] = 1 pie = Pie() pie.add('', list(education_dict.items())) pie.set_global_opts(title_opts=opts.TitleOpts(title='BOSS直聘学历要求分布图')) return pie.dump_options_with_quotes() @app.route('/welfare') def welfare(): db = pymysql.connect(host='localhost', user='root', password='123456', port=3306, db='boss_zhipin') cursor = db.cursor() sql = 'SELECT welfare FROM job_info' cursor.execute(sql) results = cursor.fetchall() welfare_list = [] for result in results: welfare_list.extend(result[0]) welfare_dict = {} for welfare in welfare_list: if welfare in welfare_dict.keys(): welfare_dict[welfare] += 1 else: welfare_dict[welfare] = 1 wordcloud = WordCloud() wordcloud.add('', list(welfare_dict.items()), word_size_range=[20, 100]) wordcloud.set_global_opts(title_opts=opts.TitleOpts(title='BOSS直聘福利词云图')) return wordcloud.dump_options_with_quotes() if __name__ == '__main__': app.run() ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值