路飞学城—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爬虫实战密训班 第二章的更多相关文章

  1. 路飞学城—Python爬虫实战密训班 第三章

    路飞学城—Python爬虫实战密训班 第三章 一.scrapy-redis插件实现简单分布式爬虫 scrapy-redis插件用于将scrapy和redis结合实现简单分布式爬虫: - 定义调度器 - ...

  2. 路飞学城Python爬虫课第一章笔记

    前言 原创文章,转载引用务必注明链接.水平有限,如有疏漏,欢迎指正. 之前看阮一峰的博客文章,介绍到路飞学城爬虫课程限免,看了眼内容还不错,就兴冲冲报了名,99块钱满足以下条件会返还并送书送视频. 缴 ...

  3. 路飞学城-Python爬虫集训-第三章

    这个爬虫集训课第三章的作业讲得是Scrapy 课程主要是使用Scrapy + Redis实现分布式爬虫 惯例贴一下作业: Python爬虫可以使用Requests库来进行简单爬虫的编写,但是Reque ...

  4. 路飞学城-Python爬虫集训-第一章

    自学Python的时候看了不少老男孩的视频,一直欠老男孩一个会员,现在99元爬虫集训果断参与. 非常喜欢Alex和武Sir的课,技术能力超强,当然讲着讲着就开起车来也说明他俩开车的技术也超级强! 以上 ...

  5. 路飞学城-Python爬虫集训-第二章

    本次爬虫集训的第二次作业是web微信. 先贴一下任务: 作业中使用到了Flask. Flask是一个使用 Python 编写的轻量级 Web 应用框架.其 WSGI 工具箱采用 Werkzeug ,模 ...

  6. 路飞学城-Python开发集训-第3章

    学习心得: 通过这一章的作业,使我对正则表达式的使用直接提升了一个level,虽然作业完成的不怎么样,重复代码有点多,但是收获还是非常大的,有点找到写代码的感觉了,遗憾的是,这次作业交过,这次集训就结 ...

  7. 路飞学城-Python开发集训-第1章

    学习体会: 在参加这次集训之前我自己学过一段时间的Python,看过老男孩的免费视频,自我感觉还行,老师写的代码基本上都能看懂,但是实际呢?....今天是集训第一次交作业的时间,突然发现看似简单升级需 ...

  8. 路飞学城-Python开发集训-第4章

    学习心得: 学习笔记: 在python中一个py文件就是一个模块 模块好处: 1.提高可维护性 2.可重用 3.避免函数名和变量名冲突 模块分为三种: 1.内置标准模块(标准库),查看所有自带和第三方 ...

  9. 路飞学城-Python开发集训-第2章

    学习心得: 这章对编码的讲解超级赞,现在对于编码终于有一点认知了,但还没有大彻大悟,还需要更加细心的琢磨一下Alex博客和视频,以前真的是被编码折磨死了,因为编码的问题而浪费的时间很多很多,现在终于感 ...

随机推荐

  1. Matplotlib 基本概念

    章节 Matplotlib 安装 Matplotlib 入门 Matplotlib 基本概念 Matplotlib 图形绘制 Matplotlib 多个图形 Matplotlib 其他类型图形 Mat ...

  2. JuJu团队1月8号工作汇报

    JuJu团队1月8号工作汇报 JuJu   Scrum 团队成员 今日工作 剩余任务 困难 飞飞 实现三维Dense 将crossentrophy和softmax连接起来 无 婷婷 完善main.jl ...

  3. 判断ES数据是否更新成功

    参考:https://stackoverflow.com/questions/38928991/how-to-detect-if-a-document-update-in-elasticsearch- ...

  4. windows目标进程注入dll

    在别的程序注入dll 步骤: ,获取目标进程ID,CreateToolhelp32Snapshot()函数; ,获取目标进程句柄,OpenProcess()函数; ,目标进程要一块内存,Virtual ...

  5. Solr查询和过滤器执行顺序剖析

    一.简介 Solr的搜索主要由两个操作组成:找到与请求参数相匹配的文档:对这些文档进行排序,返回最相关的匹配文档.默认情况下,文档根据相关度进行排序.这意味着,找到匹配的文档集之后,需要另一个操作来计 ...

  6. 010-PHP输出数组中第某个元素

    <?php $monthName = array(1 => "January", "February", "March",//初 ...

  7. System.Data.SqlClient.SqlException: 'Incorrect syntax near 'OFFSET'.

    https://www.nopcommerce.com/boards/t/54586/410-not-running-on-local-system.aspx#209684 Hello, I was ...

  8. 吴裕雄 Bootstrap 前端框架开发——Bootstrap 字体图标(Glyphicons):glyphicon glyphicon-download

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name ...

  9. QEMU 配置网络

    背景 为了 实现 uboot 中连接上 QEMU-host 的网络. 非常奇怪,本人的 系统中 存在/dev/net/tun驱动,但是 lsmod | grep tun 却没有任何结果,所以实际上,这 ...

  10. 【剑指Offer】面试题32 - III. 从上到下打印二叉树 III

    题目 请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右到左的顺序打印,第三行再按照从左到右的顺序打印,其他行以此类推. 例如: 给定二叉树: [3,9,20,nu ...