突破淘宝对于 selenium 检测

 

From:https://blog.csdn.net/qq_42196922/article/details/89400988

多加一行代码,突破淘宝模拟登录滑块:http://www.imooc.com/article/285729

爬虫自动化:https://www.jianshu.com/p/b3b92f327374

selenium 跳过 webdriver 检测并模拟登录淘宝:https://www.cnblogs.com/cloudbird/p/10524242.html

 

 

 

方法 1:利用 Chrome DevTools 协议

 

 Chrome DevTools Protocol (协议详细内容):https://chromedevtools.github.io/devtools-protocol/

之前淘宝对于 selenium 还是很友好的,后来 selenium 被检测了 window.navigator.webdriver 等参数,出滑动验证码什么的,selenium 已经很难用了,  网上大片教程都使用的 pyppeteer 修改检测 js 参数去采集,  但是发现chromium 占用内存太高,并且 pyppeteer 参数方法介绍太少,用起来不舒服。

本文介绍了另一种方法:使用 selenium 接管 chrome 浏览器

利用 Chrome DevTools 协议。它允许客户 检查 和 调试 Chrome 浏览器。

 

添加 chrome 的环境变量

 

系统环境变量 PATH 里将 chrome的路径 添加进去。

 

 

命令行下执行命令

 

打开cmd,在命令行中输入命令:

chrome.exe --remote-debugging-port=9999 --user-data-dir="C:\selenum\AutomationProfile"
 
 

对于-remote-debugging-port值,可以指定任何打开的端口。

      对于-user-data-dir 标记,指定创建新 Chrome 配置文件的目录。它是为了确保在单独的配置文件中启动 chrome,不会污染你的默认配置文件。

执行完命令后,会打开一个浏览器页面,我们输入淘宝网址(https://login.taobao.com/member/login.jhtml),输入用户名和密码,登录淘宝后用户信息就保存在 --user-data-dir="C:\selenum\AutomationProfile" 所指定的文件夹中。

 

执行 js window.open() 打不开窗口时,是因为 chrome 默认不允许弹出窗口,改下 chrome 设置就可以了
在 chrome 浏览器地址栏输入:chrome://settings/content/popups,把 已阻止(推荐)  改成 允许 即可。
或者 chrome -》设置 -》高级 -》隐私设置和安全性 -》网站设置 -》弹出式窗口和重定向,也可以设置。

 

 

不要关闭上面浏览器,然后执行 python 代码

 

python 代码:

在淘宝搜索 "电脑" 关键字,并打印前 5 页 所有 搜索内容


 
 
  1. import os
  2. import time
  3. import random
  4. from selenium import webdriver
  5. from selenium.webdriver.chrome.options import Options
  6. from selenium.webdriver.support.ui import WebDriverWait
  7. from selenium.webdriver.common.by import By
  8. from selenium.webdriver.support import expected_conditions as EC
  9. # from selenium.webdriver.common.action_chains import ActionChains
  10. def main():
  11. # os.system(r'C:\Users\Administrator\AppData\Local\Google\Chrome\Application/chrome.exe --remote-debugging-port=9999 --user-data-dir="C:\selenum\AutomationProfile"')
  12. chrome_debug_port = 9999
  13. chrome_options = Options()
  14. # chrome_options.add_argument('--headless')
  15. chrome_options.add_experimental_option( "debuggerAddress", f"127.0.0.1:{chrome_debug_port}")
  16. browser = webdriver.Chrome(chrome_options=chrome_options)
  17. wait = WebDriverWait(browser, 5)
  18. print(browser.title)
  19. # 当前句柄
  20. current_handle = browser.current_window_handle
  21. # browser.execute_script('window.open("https://login.taobao.com/member/login.jhtml")')
  22. browser.execute_script( 'window.open("http://www.baidu.com")')
  23. # 所有句柄
  24. all_handle = browser.window_handles
  25. second_handle = all_handle[ -1]
  26. # 切回first
  27. browser.switch_to.window(current_handle)
  28. url = 'https://s.taobao.com/search?q=电脑'
  29. browser.get(url)
  30. produce_info_xpath = '//div[contains(@class, "J_MouserOnverReq")]//div[@class="row row-2 title"]/a'
  31. produce_info = browser.find_elements_by_xpath(produce_info_xpath)
  32. for produce in produce_info:
  33. print(produce.text.replace( ' ', ''))
  34. # 这里是演示,所以只爬了前 5 页
  35. for page_num in range( 2, 6):
  36. next_page_xpath = '//li[@class="item next"]'
  37. next_page = browser.find_element_by_xpath(next_page_xpath)
  38. next_page_enable = False if 'disabled' in next_page.get_attribute( 'class') else True
  39. if next_page_enable:
  40. print( '*' * 100)
  41. print( f'第 {page_num} 页')
  42. next_page.click()
  43. # browser.refresh()
  44. produce_info_xpath = '//div[contains(@class, "J_MouserOnverReq")]//div[@class="row row-2 title"]/a'
  45. wait.until(EC.presence_of_all_elements_located((By.XPATH, produce_info_xpath)))
  46. time.sleep(random.randint( 3, 5))
  47. produce_info = browser.find_elements_by_xpath(produce_info_xpath)
  48. for produce in produce_info:
  49. print(produce.text.replace( ' ', ''))
  50. else:
  51. break
  52. if __name__ == '__main__':
  53. main()

执行结果截图:

 

代码 2(根据关键字搜索,然后抓取 店铺名,店铺地址,店铺电话,):


 
 
  1. # -*- coding: utf-8 -*-
  2. import time
  3. import random
  4. import parsel
  5. import re
  6. from selenium import webdriver
  7. from selenium.webdriver.chrome.options import Options
  8. from selenium.webdriver.support.ui import WebDriverWait
  9. from selenium.webdriver.common.by import By
  10. from selenium.webdriver.support import expected_conditions as EC
  11. # from selenium.webdriver.common.action_chains import ActionChains
  12. class TaoBaoSearch(object):
  13. def __init__(self):
  14. super(TaoBaoSearch, self).__init__()
  15. self.browser = None
  16. self.wait = None
  17. self.master_handler = None
  18. self.slaver_handler = None
  19. self.temp = None
  20. self.browser_init()
  21. def browser_init(self):
  22. chrome_debug_port = 9999
  23. chrome_options = Options()
  24. chrome_options.add_experimental_option( "debuggerAddress", f"127.0.0.1:{chrome_debug_port}")
  25. # chrome_options.add_argument('--headless')
  26. self.browser = webdriver.Chrome(chrome_options=chrome_options)
  27. self.wait = WebDriverWait(self.browser, 5)
  28. all_handler = self.browser.window_handles
  29. if len(all_handler) >= 1:
  30. for index in all_handler[ 1:]:
  31. self.browser.switch_to.window(index)
  32. self.browser.close()
  33. # self.master_handler = self.browser.current_window_handle
  34. self.master_handler = self.browser.window_handles[ 0]
  35. self.browser.switch_to.window(self.master_handler)
  36. self.browser.execute_script( 'window.open()')
  37. # self.browser.execute_script('window.open("_blank")')
  38. handlers = self.browser.window_handles
  39. self.slaver_handler = handlers[ -1]
  40. # print(self.browser.title)
  41. def get_detail_info(self, shop_url=None):
  42. # 切换到 从 窗口
  43. self.browser.switch_to.window(self.slaver_handler)
  44. self.browser.get(shop_url)
  45. html = self.browser.page_source
  46. html = html.replace( '&lt;', '<').replace( '&gt;', '>')
  47. # print(html)
  48. s_html = parsel.Selector(text=html)
  49. shop_keeper_xpath = '//div[@class="extend"]//li[@class="shopkeeper"]//a/text()'
  50. shop_keeper = s_html.xpath(shop_keeper_xpath).extract_first()
  51. phone_reg = '联系电话:(\d+-?\d+)|联系手机:(\d+)'
  52. phone = re.findall(phone_reg, html)
  53. # 处理完后 一定要切换到 主 窗口
  54. self.browser.switch_to.window(self.master_handler)
  55. return shop_keeper, phone
  56. def process_item(self, item):
  57. self.temp = None
  58. shop_xpath = './/div[@class="shop"]//a'
  59. local_xpath = './/div[@class="location"]'
  60. shop = item.find_element_by_xpath(shop_xpath).text
  61. shop_url = item.find_element_by_xpath(shop_xpath).get_attribute( 'href')
  62. local = item.find_element_by_xpath(local_xpath).text
  63. shop_keeper, phone = self.get_detail_info(shop_url)
  64. if phone:
  65. print( f'shop : {shop}')
  66. print( f'local : {local}')
  67. print( f'shop_url : {shop_url}')
  68. print( f'shop_keeper : {shop_keeper}')
  69. print( f'phone : {phone}')
  70. with open( './info.txt', 'a+') as f:
  71. f.write(shop + ',')
  72. f.write(local + ',')
  73. f.write(shop_url + ',')
  74. f.write(shop_keeper + ',')
  75. f.write( f'{phone}')
  76. f.write( '\n')
  77. def main(self):
  78. # 切回 主 窗口
  79. self.browser.switch_to.window(self.master_handler)
  80. key_word = input( '输入淘宝搜索关键字:')
  81. if not key_word:
  82. print( '没有输入关键字。默认搜索 “手机”')
  83. key_word = '手机'
  84. url = f'https://s.taobao.com/search?q={key_word}'
  85. self.browser.get(url)
  86. shop_and_local_xpath = '//div[contains(@class, "J_MouserOnverReq")]//div[@class="row row-3 g-clearfix"]'
  87. shop_and_local = self.browser.find_elements_by_xpath(shop_and_local_xpath)
  88. for item in shop_and_local:
  89. self.process_item(item)
  90. # 这里是演示,所以只爬了前 5 页
  91. for page_num in range( 2, 6):
  92. next_page_xpath = '//li[@class="item next"]'
  93. next_page = self.browser.find_element_by_xpath(next_page_xpath)
  94. next_page_enable = False if 'disabled' in next_page.get_attribute( 'class') else True
  95. if next_page_enable:
  96. print( '*' * 100)
  97. print( f'第 {page_num} 页')
  98. next_page.click()
  99. # self.browser.refresh()
  100. self.wait.until(EC.presence_of_all_elements_located((By.XPATH, shop_and_local_xpath)))
  101. time.sleep(random.randint( 3, 5))
  102. shop_and_local = self.browser.find_elements_by_xpath(shop_and_local_xpath)
  103. for item in shop_and_local:
  104. self.process_item(item)
  105. else:
  106. break
  107. if __name__ == '__main__':
  108. tb = TaoBaoSearch()
  109. tb.main()

抓取信息保存到 info.txt ,文件截图:

 

 

改进:

上面是一直有浏览器窗口的,没法使用 无头模式,可以使用 --user-data-dir 参数,然后设置无头模式。

如果想改变 Chrome 位置,可以设置  chrome_options.binary_location 为 chrome.exe 路径即可。


 
 
  1. from selenium import webdriver
  2. from selenium.webdriver.chrome.options import Options
  3. if __name__ == '__main__':
  4. chrome_options = Options()
  5. # 不使用默认的Chrome安装版本时,可以设置binary_location 指定 Chrome 路径 。
  6. # chrome 和 Chromium 对应 chromedriver.exe 版本不一样
  7. chrome_options.binary_location = r'D:\chrome\chrome.exe'
  8. # chrome_options.binary_location = r'D:\Chromium\chrome.exe'
  9. # chrome_options.add_argument('--headless')
  10. chrome_options.add_argument( "--no-sandbox")
  11. chrome_options.add_argument( 'disable-infobars')
  12. chrome_options.add_argument( r'--user-data-dir=D:\chrome\userdatadir')
  13. # chrome_options.add_argument(r'--user-data-dir=D:\Chromium\userdatadir')
  14. browser = webdriver.Chrome(
  15. chrome_options=chrome_options,
  16. executable_path= r'D:\chrome\chromedriver.exe'
  17. # executable_path=r'D:\Chromium\chromedriver.exe'
  18. )
  19. browser.get( 'https://www.taobao.com/')
  20. user_name_xpath = '//div[@class="site-nav-user"]/a'
  21. user_name = browser.find_element_by_xpath(user_name_xpath).text
  22. print(user_name)

结果截图:

可以看到 无头模式下,使用 --user-data-dir 参数,可以登录淘宝。前提需要先手动登录淘宝,拿到登录信息的文件夹。

 

 

方法 2:js 注入,修改浏览器特征

 

执行代码后,手动输入用户名和密码,滑动滑块,可以正常跳转到登录后个人页面。

提示:这个手动滑动滑块有一定的失败几率,有时候失败几率还很高。有时一次就可以滑过,有时好多次都过不去。

示例代码:


 
 
  1. import asyncio
  2. from pyppeteer import launch
  3. width, height = 1366, 768
  4. js1 = '''() =>{Object.defineProperties(navigator,{ webdriver:{ get: () => false}})}'''
  5. js2 = '''() => {alert(window.navigator.webdriver)}'''
  6. js3 = '''() => {window.navigator.chrome = {runtime: {}, }; }'''
  7. js4 = '''() =>{Object.defineProperty(navigator, 'languages', {get: () => ['en-US', 'en']});}'''
  8. js5 = '''() =>{Object.defineProperty(navigator, 'plugins', {get: () => [1, 2, 3, 4, 5,6],});}'''
  9. async def page_evaluate(page):
  10. # 替换淘宝在检测浏览时采集的一些参数
  11. # 需要注意,在测试的过程中发现登陆成功后页面的该属性又会变成True
  12. # 所以在每次重新加载页面后要重新设置该属性的值。
  13. await page.evaluate( '''() =>{ Object.defineProperties(navigator,{ webdriver:{ get: () => false } }) }''')
  14. await page.evaluate( '''() =>{ window.navigator.chrome = { runtime: {}, }; }''')
  15. await page.evaluate( '''() =>{ Object.defineProperty(navigator, 'languages', { get: () => ['en-US', 'en'] }); }''')
  16. await page.evaluate( '''() =>{ Object.defineProperty(navigator, 'plugins', { get: () => [1, 2, 3, 4, 5,6], }); }''')
  17. async def main():
  18. browser = await launch(
  19. headless= False,
  20. # userDataDir='./userdata',
  21. args=[ '--disable-infobars', f'--window-size={width},{height}', '--no-sandbox']
  22. )
  23. page = await browser.newPage()
  24. await page.setViewport(
  25. {
  26. "width": width,
  27. "height": height
  28. }
  29. )
  30. # url = 'https://www.taobao.com'
  31. url = 'https://login.taobao.com/member/login.jhtml'
  32. await page.goto(url=url)
  33. await page.evaluate(js1)
  34. await page.evaluate(js3)
  35. await page.evaluate(js4)
  36. await page.evaluate(js5)
  37. # await page_evaluate(page)
  38. await asyncio.sleep( 100)
  39. # await browser.close()
  40. asyncio.get_event_loop().run_until_complete(main())

 

 

方法 3:将 模拟浏览器 设置为 开发者模式

 

好像现在这种方法不好用了。。。。。。。。

示例代码:


 
 
  1. chrome_options = Options()
  2. # 制定 chrome.exe 路径名
  3. # chrome_options.binary_location = f"{current_dir}\\chrome\\chrome.exe"
  4. # 此步骤很重要,设置为开发者模式,防止被各大网站识别出来使用了Selenium
  5. chrome_options.add_experimental_option( 'excludeSwitches', [ 'enable-automation'])
  6. # chrome_options.add_argument("--headless")
  7. chrome_options.add_argument( "disable-infobars")
  8. chrome_options.add_argument( "--no-sandbox")
  9. chrome_options.add_argument( f"--user-data-dir={current_dir}\\chrome\\userdatadir")
  10. browser = webdriver.Chrome(
  11. chrome_options=chrome_options,
  12. executable_path= f'{current_dir}\\chrome\\chromedriver.exe'
  13. )

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值