动态加载的数据是不能直接通过网址访问的。
需通过抓包工具。
全局搜索。

chromedriver下载与安装方法,亲测可用

selenium模块的基本使用

问题:selenium模块和爬虫之间具有怎样的关联?
- 便捷的获取网站中动态加载的数据
- 便捷实现模拟登录

什么是selenium模块?
- 基于浏览器自动化的一个模块。

selenium使用流程

  • 环境安装:pip install selenium

  • 下载一个浏览器的驱动程序(谷歌浏览器)

  1. from selenium import webdriver
  2. # 返回一个浏览器对象,实例化了一个浏览器对象
  3. bro = webdriver.ChromiumEdge(executable_path='./msedgedriver.exe')

编写基于浏览器自动化的操作代码

  1. #!/usr/bin/env python
  2. # -*- coding:utf-8 -*-
  3. # @Time : 2022/4/12 9:15
  4. # @Author : hq
  5. from selenium import webdriver
  6. from lxml import etree
  7. # 返回一个浏览器对象,实例化了一个浏览器对象
  8. bro = webdriver.ChromiumEdge(executable_path='./msedgedriver.exe')
  9. # 让浏览器发起一个指定url对应请求
  10. bro.get('https://ech.xmsmjk.com/ehcweb/h5/index.html?v=1472743999281299457#/eleLogin/ch')
  11. # page_source获取浏览器当前页面的页码源码数据
  12. page_text = bro.page_source
  • 发起请求:get(url)

  • 标签定位:find系列的方法
    image.png

  • 标签交互:send_keys(‘xxx’)

  • 执行js程序:excute_script(‘jsCode’)
    开发者工具:console
    bro.execute_script(‘window.scrollTo(0,document.body.scrollHeight)’)
  • 前进,后退:back(),forward()
  • 关闭浏览器:quit()
  1. from selenium import webdriver
  2. from time import sleep
  3. bro = webdriver.ChromiumEdge(executable_path='./msedgedriver.exe')
  4. bro.get('https://www.taobao.com/')
  5. # 标签定位
  6. search_input = bro.find_element_by_id('q')
  7. # 标签交互
  8. search_input.send_keys('Iphone')
  9. # 执行一组js程序
  10. bro.execute_script('window.scrollTo(0,document.body.scrollHeight)')
  11. sleep(2)
  12. # 点击搜索按钮
  13. btn = bro.find_element_by_css_selector('.btn-search')
  14. btn.click()
  15. bro.get('https://www.baidu.com')
  16. sleep(2)
  17. # 回退
  18. bro.back()
  19. sleep(2)
  20. # 前进
  21. bro.forward()
  22. sleep(5)
  23. bro.quit()

动作链、selenium处理iframe

页面嵌套子页面,可以由iframe实现。

iframe

需要切换浏览器标签定位的作用域。

  1. #如果定位的标签是存在于iframe标签之中的则必须通过如下操作在进行标签定位
  2. bro.switch_to.frame('iframeResult')#切换浏览器标签定位的作用域
  3. div = bro.find_element_by_id('draggable')

动作链

  1. #导入动作链对应的类
  2. from selenium.webdriver import ActionChains
  3. #动作链
  4. action = ActionChains(bro)
  5. #点击长按指定的标签
  6. action.click_and_hold(div)
  7. for i in range(5):
  8. #perform()立即执行动作链操作
  9. #move_by_offset(x,y):x水平方向 y竖直方向,偏移
  10. action.move_by_offset(17,0).perform()
  11. sleep(0.5)
  12. #释放动作链
  13. action.release()

动作链(拖动):
from selenium.webdriver import ActionChains
- 实例化一个动作链对象:action = ActionChains(bro)
- click_and_hold(div):长按且点击操作
- move_by_offset(x,y):滑动、拖动
- perform()让动作链立即执行
- action.release()释放动作链对象

无头浏览器+反检测

让浏览器弹出应该是无弹出的。不要有可视化界面。

  1. from selenium import webdriver
  2. from time import sleep
  3. #实现无可视化界面
  4. from selenium.webdriver.chrome.options import Options
  5. #实现规避检测
  6. from selenium.webdriver import ChromeOptions
  7. #实现无可视化界面的操作
  8. chrome_options = Options()
  9. chrome_options.add_argument('--headless')
  10. chrome_options.add_argument('--disable-gpu')
  11. #实现规避检测
  12. option = ChromeOptions()
  13. option.add_experimental_option('excludeSwitches', ['enable-automation'])
  14. #如何实现让selenium规避被检测到的风险
  15. bro = webdriver.Chrome(executable_path='./chromedriver',chrome_options=chrome_options,options=option)
  16. #无可视化界面(无头浏览器) phantomJs
  17. bro.get('https://www.baidu.com')
  18. print(bro.page_source)
  19. sleep(2)
  20. bro.quit()

爬虫selenium(edge无头浏览器+规避检测风险)

12306模拟登录

超级鹰:http://www.chaojiying.com/about.html
注册:普通用户
登录:普通用户
题分查询:充值
- 创建一个软件(id)
- 下载示例代码

12306模拟登录编码流程:
使用selenium打开登录页面
对当前selenium打开的这张页面进行截图
对当前图片局部区域(验证码图片)进行裁剪
好处:将验证码图片和模拟登录进行一一对应。
使用超级鹰识别验证码图片(坐标)
使用动作链根据坐标实现点击操作
录入用户名密码,点击登录按钮实现登录

  1. #下述代码为超级鹰提供的示例代码
  2. import requests
  3. from hashlib import md5
  4. class Chaojiying_Client(object):
  5. def __init__(self, username, password, soft_id):
  6. self.username = username
  7. password = password.encode('utf8')
  8. self.password = md5(password).hexdigest()
  9. self.soft_id = soft_id
  10. self.base_params = {
  11. 'user': self.username,
  12. 'pass2': self.password,
  13. 'softid': self.soft_id,
  14. }
  15. self.headers = {
  16. 'Connection': 'Keep-Alive',
  17. 'User-Agent': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)',
  18. }
  19. def PostPic(self, im, codetype):
  20. """
  21. im: 图片字节
  22. codetype: 题目类型 参考 http://www.chaojiying.com/price.html
  23. """
  24. params = {
  25. 'codetype': codetype,
  26. }
  27. params.update(self.base_params)
  28. files = {'userfile': ('ccc.jpg', im)}
  29. r = requests.post('http://upload.chaojiying.net/Upload/Processing.php', data=params, files=files, headers=self.headers)
  30. return r.json()
  31. def ReportError(self, im_id):
  32. """
  33. im_id:报错题目的图片ID
  34. """
  35. params = {
  36. 'id': im_id,
  37. }
  38. params.update(self.base_params)
  39. r = requests.post('http://upload.chaojiying.net/Upload/ReportError.php', data=params, headers=self.headers)
  40. return r.json()
  41. # chaojiying = Chaojiying_Client('bobo328410948', 'bobo328410948', '899370') #用户中心>>软件ID 生成一个替换 96001
  42. # im = open('12306.jpg', 'rb').read() #本地图片文件路径 来替换 a.jpg 有时WIN系统须要//
  43. # print(chaojiying.PostPic(im, 9004)['pic_str'])
  44. #上述代码为超级鹰提供的示例代码
  45. #使用selenium打开登录页面
  46. from selenium import webdriver
  47. import time
  48. from PIL import Image
  49. from selenium.webdriver import ActionChains
  50. bro = webdriver.Chrome(executable_path='./chromedriver')
  51. bro.get('https://kyfw.12306.cn/otn/login/init')
  52. time.sleep(1)
  53. #save_screenshot就是将当前页面进行截图且保存
  54. bro.save_screenshot('aa.png')
  55. #确定验证码图片对应的左上角和右下角的坐标(裁剪的区域就确定)
  56. code_img_ele = bro.find_element_by_xpath('//*[@id="loginForm"]/div/ul[2]/li[4]/div/div/div[3]/img')
  57. location = code_img_ele.location # 验证码图片左上角的坐标 x,y
  58. print('location:',location)
  59. size = code_img_ele.size #验证码标签对应的长和宽
  60. print('size:',size)
  61. #左上角和右下角坐标
  62. rangle = (
  63. int(location['x']), int(location['y']), int(location['x'] + size['width']), int(location['y'] + size['height']))
  64. #至此验证码图片区域就确定下来了
  65. i = Image.open('./aa.png')
  66. code_img_name = './code.png'
  67. #crop根据指定区域进行图片裁剪
  68. frame = i.crop(rangle)
  69. frame.save(code_img_name)
  70. #将验证码图片提交给超级鹰进行识别
  71. chaojiying = Chaojiying_Client('bobo328410948', 'bobo328410948', '899370') #用户中心>>软件ID 生成一个替换 96001
  72. im = open('code.png', 'rb').read() #本地图片文件路径 来替换 a.jpg 有时WIN系统须要//
  73. print(chaojiying.PostPic(im, 9004)['pic_str'])
  74. result = chaojiying.PostPic(im, 9004)['pic_str']
  75. all_list = [] #要存储即将被点击的点的坐标 [[x1,y1],[x2,y2]]
  76. if '|' in result:
  77. list_1 = result.split('|')
  78. count_1 = len(list_1)
  79. for i in range(count_1):
  80. xy_list = []
  81. x = int(list_1[i].split(',')[0])
  82. y = int(list_1[i].split(',')[1])
  83. xy_list.append(x)
  84. xy_list.append(y)
  85. all_list.append(xy_list)
  86. else:
  87. x = int(result.split(',')[0])
  88. y = int(result.split(',')[1])
  89. xy_list = []
  90. xy_list.append(x)
  91. xy_list.append(y)
  92. all_list.append(xy_list)
  93. print(all_list)
  94. #遍历列表,使用动作链对每一个列表元素对应的x,y指定的位置进行点击操作
  95. for l in all_list:
  96. x = l[0]
  97. y = l[1]
  98. ActionChains(bro).move_to_element_with_offset(code_img_ele, x, y).click().perform()
  99. time.sleep(0.5)
  100. bro.find_element_by_id('username').send_keys('www.zhangbowudi@qq.com')
  101. time.sleep(2)
  102. bro.find_element_by_id('password').send_keys('bobo_15027900535')
  103. time.sleep(2)
  104. bro.find_element_by_id('loginSub').click()
  105. time.sleep(30)
  106. bro.quit()