路飞学城—Python爬虫实战密训班 第二章
路飞学城—Python爬虫实战密训班 第二章
一、Selenium基础
Selenium是一个第三方模块,可以完全模拟用户在浏览器上操作(相当于在浏览器上点点点)。
1.安装
- pip install selenium
2.优缺点
- 无需查看和确定请求头请求体等数据细节,直接模拟人点击浏览器的行为
- 效率不高
3.依赖驱动:
- Firefox
https://github.com/mozilla/geckodriver/releases
- Chrome
http://chromedriver.storage.googleapis.com/index.html
4.与selenium相关的基本操作
from selenium import webdriver # 配置驱动
#驱动一定要自己下载并放在一个目录,否则会出错 option = webdriver.ChromeOptions()
driver = webdriver.Chrome('/Users/wupeiqi/drivers/chromedriver', chrome_options=option) # 1. 控制浏览器打开指定页面
driver.get("https://dig.chouti.com/all/hot/recent/1") # 2. 找到登录按钮
btn_login = driver.find_element_by_xpath('//*[@id="login-link-a"]')
# 3. 点击按钮
btn_login.click() # 4. 找到手机标签
input_user = driver.find_element_by_xpath('//*[@id="mobile"]')
# 5. 找到密码标签
input_pwd = driver.find_element_by_xpath('//*[@id="mbpwd"]') # 6. 输入用户名
input_user.send_keys('13121758648')
# 7. 输入密码
input_pwd.send_keys('woshiniba') # 8. 点击登录按钮
input_submit = driver.find_element_by_xpath(
'//*[@id="footer-band"]/div[5]/div/div/div[1]/div[2]/div[4]/div[2]/div/span[1]')
input_submit.click() print(driver.get_cookies()) # # 9. 点击跳转
# news = driver.find_element_by_xpath('//*[@id="newsContent20646261"]/div[1]/a[1]')
# # news.click()
# driver.execute_script("arguments[0].click();", news) # 10.管理浏览器
# driver.close()
二、破解滑动验证码
WuSir为我们带来的精彩的讲解,从__main__的主函数调用开始,先讲了图片的截取和距离的测算,接下来分析了怎么模拟人类行为的滑动过程,通过速度和加速度的空值实现,而且会故意制造匹配之后的小幅振动行为,最后点击确定就可以破解该验证码,重点是像素的选择和速度的调节,感谢!
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
import os
import shutil
from PIL import Image
import time def get_snap(driver):
driver.save_screenshot('full_snap.png')
page_snap_obj = Image.open('full_snap.png') return page_snap_obj def get_image(driver):
img = driver.find_element_by_class_name('geetest_canvas_img')
time.sleep(2)
location = img.location
size = img.size left = location['x']
top = location['y']
right = left + size['width']
bottom = top + size['height'] page_snap_obj = get_snap(driver) image_obj = page_snap_obj.crop((left * 2, top * 2, right * 2, bottom * 2))
# image_obj.show()
with open('code.png', 'wb') as f:
image_obj.save(f, format='png')
return image_obj def get_distance(image1, image2):
# start = 0
# threhold = 70
# for i in range(start, image1.size[0]):
# for j in range(0, image1.size[1]):
# rgb1 = image1.load()[i, j]
# rgb2 = image2.load()[i, j]
# res1 = abs(rgb1[0] - rgb2[0])
# res2 = abs(rgb1[1] - rgb2[1])
# res3 = abs(rgb1[2] - rgb2[2])
# # print(res1,res2,res3)
# if not (res1 < threhold and res2 < threhold and res3 < threhold):
# print(111111, i, j)
# return i - 13
# print(2222, i, j)
# return i - 13
start = 0
threhold = 70
v = []
for i in range(start, image1.size[0]):
for j in range(0, image1.size[1]):
rgb1 = image1.load()[i, j]
rgb2 = image2.load()[i, j]
res1 = abs(rgb1[0] - rgb2[0])
res2 = abs(rgb1[1] - rgb2[1])
res3 = abs(rgb1[2] - rgb2[2]) if not (res1 < threhold and res2 < threhold and res3 < threhold):
print(i)
if i not in v:
v.append(i) stop = 0
for i in range(0, len(v)):
val = i + v[0]
if v[i] != val:
stop = v[i]
break width = stop - v[0]
print(stop, v[0], width)
return width def get_tracks(distance):
import random
exceed_distance = random.randint(0, 5)
distance += exceed_distance # 先滑过一点,最后再反着滑动回来
v = 0
t = 0.2
forward_tracks = [] current = 0
mid = distance * 3 / 5
while current < distance:
if current < mid:
a = random.randint(1, 3)
else:
a = random.randint(1, 3)
a = -a
s = v * t + 0.5 * a * (t ** 2)
v = v + a * t
current += s
forward_tracks.append(round(s)) # 反着滑动到准确位置
v = 0
t = 0.2
back_tracks = [] current = 0
mid = distance * 4 / 5
while abs(current) < exceed_distance:
if current < mid:
a = random.randint(1, 3)
else:
a = random.randint(-3, -5)
a = -a
s = -v * t - 0.5 * a * (t ** 2)
v = v + a * t
current += s
back_tracks.append(round(s))
return {'forward_tracks': forward_tracks, 'back_tracks': list(reversed(back_tracks))} def crack(driver): # 破解滑动认证
# 1、点击按钮,得到没有缺口的图片
button = driver.find_element_by_xpath('//*[@id="embed-captcha"]/div/div[2]/div[1]/div[3]')
button.click() # 2、获取没有缺口的图片
image1 = get_image(driver) # 3、点击滑动按钮,得到有缺口的图片
button = driver.find_element_by_class_name('geetest_slider_button')
button.click() # 4、获取有缺口的图片
image2 = get_image(driver) # 5、对比两种图片的像素点,找出位移
distance = get_distance(image1, image2)
print(distance)
#
# 6、模拟人的行为习惯,根据总位移得到行为轨迹
tracks = get_tracks(int(distance / 2)) # 7、按照行动轨迹先正向滑动,后反滑动
button = driver.find_element_by_class_name('geetest_slider_button')
ActionChains(driver).click_and_hold(button).perform() # 正常人类总是自信满满地开始正向滑动,自信地表现是疯狂加速
for track in tracks['forward_tracks']:
ActionChains(driver).move_by_offset(xoffset=track, yoffset=0).perform() # 结果傻逼了,正常的人类停顿了一下,回过神来发现,卧槽,滑过了,然后开始反向滑动
time.sleep(0.5)
for back_track in tracks['back_tracks']:
ActionChains(driver).move_by_offset(xoffset=back_track, yoffset=0).perform()
#
# # 小范围震荡一下,进一步迷惑极验后台,这一步可以极大地提高成功率
ActionChains(driver).move_by_offset(xoffset=3, yoffset=0).perform()
ActionChains(driver).move_by_offset(xoffset=-3, yoffset=0).perform() # # 成功后,骚包人类总喜欢默默地欣赏一下自己拼图的成果,然后恋恋不舍地松开那只脏手
time.sleep(0.5)
ActionChains(driver).release().perform() def login_luffy(username, password):
driver = webdriver.Chrome('/Users/wupeiqi/drivers/chromedriver')
driver.set_window_size(960, 800)
try:
# 1、输入账号密码回车
driver.implicitly_wait(3)
driver.get('https://www.luffycity.com/login') input_username = driver.find_element_by_xpath('//*[@id="router-view"]/div/div/div[2]/div[2]/input[1]')
input_pwd = driver.find_element_by_xpath('//*[@id="router-view"]/div/div/div[2]/div[2]/input[2]') input_username.send_keys(username)
input_pwd.send_keys(password) # 2、破解滑动认证
crack(driver) time.sleep(10) # 睡时间长一点,确定登录成功
finally:
pass
# driver.close() if __name__ == '__main__':
login_luffy(username='wupeiqi', password='123123123')
三:总结
前半段的直播都是由咸湿的,哦不对、是亲切的Alex老师为我们分享了关于职场方面的一些东西,尤其是咸湿的,哦不对、是亲切的Alex老师用他曾经的经历来讲述这些东西,这些经验和思想,听完后对大家讨论得都很热烈,挺受启发的。
通过学习selenium模块,使得部分对于很复杂的爬虫,用selenium做起来还是比较方便的。但如果使用selenium模块的话,对于爬虫程序可以说基本毫无性能可言,一般的解决方案可以通过selenium + 其它模块一起配合使用来相互弥补。最后,WuSir通过selenium 和 PIL模块一起配合使用,破解了极验的滑动验证码、但此方式有个大问题,只能处理简单的图片,对于复杂的图片命中率会不高,面对更加复杂的验证码只能通过打码平台来解决了。
路飞学城—Python爬虫实战密训班 第二章的更多相关文章
- 路飞学城—Python爬虫实战密训班 第三章
路飞学城—Python爬虫实战密训班 第三章 一.scrapy-redis插件实现简单分布式爬虫 scrapy-redis插件用于将scrapy和redis结合实现简单分布式爬虫: - 定义调度器 - ...
- 路飞学城Python爬虫课第一章笔记
前言 原创文章,转载引用务必注明链接.水平有限,如有疏漏,欢迎指正. 之前看阮一峰的博客文章,介绍到路飞学城爬虫课程限免,看了眼内容还不错,就兴冲冲报了名,99块钱满足以下条件会返还并送书送视频. 缴 ...
- 路飞学城-Python爬虫集训-第三章
这个爬虫集训课第三章的作业讲得是Scrapy 课程主要是使用Scrapy + Redis实现分布式爬虫 惯例贴一下作业: Python爬虫可以使用Requests库来进行简单爬虫的编写,但是Reque ...
- 路飞学城-Python爬虫集训-第一章
自学Python的时候看了不少老男孩的视频,一直欠老男孩一个会员,现在99元爬虫集训果断参与. 非常喜欢Alex和武Sir的课,技术能力超强,当然讲着讲着就开起车来也说明他俩开车的技术也超级强! 以上 ...
- 路飞学城-Python爬虫集训-第二章
本次爬虫集训的第二次作业是web微信. 先贴一下任务: 作业中使用到了Flask. Flask是一个使用 Python 编写的轻量级 Web 应用框架.其 WSGI 工具箱采用 Werkzeug ,模 ...
- 路飞学城-Python开发集训-第3章
学习心得: 通过这一章的作业,使我对正则表达式的使用直接提升了一个level,虽然作业完成的不怎么样,重复代码有点多,但是收获还是非常大的,有点找到写代码的感觉了,遗憾的是,这次作业交过,这次集训就结 ...
- 路飞学城-Python开发集训-第1章
学习体会: 在参加这次集训之前我自己学过一段时间的Python,看过老男孩的免费视频,自我感觉还行,老师写的代码基本上都能看懂,但是实际呢?....今天是集训第一次交作业的时间,突然发现看似简单升级需 ...
- 路飞学城-Python开发集训-第4章
学习心得: 学习笔记: 在python中一个py文件就是一个模块 模块好处: 1.提高可维护性 2.可重用 3.避免函数名和变量名冲突 模块分为三种: 1.内置标准模块(标准库),查看所有自带和第三方 ...
- 路飞学城-Python开发集训-第2章
学习心得: 这章对编码的讲解超级赞,现在对于编码终于有一点认知了,但还没有大彻大悟,还需要更加细心的琢磨一下Alex博客和视频,以前真的是被编码折磨死了,因为编码的问题而浪费的时间很多很多,现在终于感 ...
随机推荐
- POJ 1979 Red and Black 四方向棋盘搜索
Red and Black Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 50913 Accepted: 27001 D ...
- Ternsorflow 学习:000-在 Ubuntu 16.04 上安装并使用 TensorFlow_v1.14 (改)
声明:本人已经对原文链接根据情况做出合理的改动. 本系列文章使用的是Tensorflow v1.14 引言 TensorFlow 是由谷歌构建的用于训练神经网络的开源机器学习软件.TensorFlow ...
- 开发工具类(eclipse、安卓SDK) 镜像站
1.eclipse 中国科技大学:http://mirrors.ustc.edu.cn/eclipse/ 中国科学院:http://mirrors.opencas.cn/eclipse/ 东北大学:h ...
- imple-unpack---攻防世界
拿到题目查壳没有发现.题目已经明确说了,基本上是有壳的,Linux下面看看 应该就是upx的壳了,下载upx进行脱壳,https://sourceforge.net/projects/upx/file ...
- mysql 添加索引语句
1.PRIMARY KEY(主键索引) mysql>ALTER TABLE `table_name` ADD PRIMARY KEY ( `column` ) 2. ...
- django中使用ORM模型修改数据库的表名
在django中,使用models.py创建好一张表后,如果不指定表的名字,那么表的名字就默认为 model_modelname 例如: class Book(models.Model): id = ...
- crashpad 应用程序异常解决方案
衡量某个应用程序的稳定性的一个重要指标即它自身的崩溃率的统计,但是如何判断应用程序崩溃,且上报崩溃产生的dmp文件进行分析? google提供了一套开源的系统 Crashpad,详细了解参见 http ...
- 基于Hadoop3.1.2集群的Hive3.1.2安装(有不少坑)
前置条件: 已经安装好了带有HDFS, MapReduce, Yarn 功能的 Hadoop集群 链接: ubuntu18.04.2 hadoop3.1.2+zookeeper3.5.5高可用完全分布 ...
- 在excel表格里,为所有数字添上绿色小三角
在excel表格里,为所有数字添上绿色小三角的方法有4种: 1. 为一个单元格添加:直接在单元格里添加一个英文的逗号 2. 为一列数据添加:选中要添加绿色小三角的列,选择 数据-->分列--&g ...
- 【LeetCode】226. 翻转二叉树
题目 翻转一棵二叉树. 示例: 输入: 4 / \ 2 7 / \ / \ 1 3 6 9 输出: 4 / \ 7 2 / \ / \ 9 6 3 1 本题同[剑指Offer]面试题27. 二叉树的镜 ...