关闭

如何避免Selenium爬虫被网站识破

发表于:2023-7-03 09:36

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:小白学大数据    来源:知乎

  在对一些需要进行登陆操作的网站爬取时,通常都会使用到Selenium。但是Selenium爬虫在爬取数据时也是会被网站检测到,这是因为Selenium模拟了浏览器行为,而相对于真实用户的浏览器,Selenium模拟无法识别JavaScript代码和CSS文件。此外,网站也可能通过检测请求头、IP地址、Cookie等信息来判断是否是爬虫。 接下来我们就详细的来了解下这些原因是怎么产生的。 
  1、请求头信息:一般情况下Selenium提供的请求头信息与正常的浏览器请求头略有不同,所以需要自定义User-Agent字段让请求头更像正常的浏览器。 
  2、IP封禁或限制访问:如果频繁使用同一个IP地址进行数据爬取,服务器可能会将该IP地址视为恶意IP并加入黑名单。 
  3、Cookie验证:部分网站可能会在登录后,在后续的每个请求中都要求携带相关的Cookie信息。 
  4、页面加载速度:如果程序访问频率过高,页面加载时间却显示异常迅速,网站越是往后就越容易加强反爬虫措施了。 
  以下就是针对上述问题而提供的解决方式: 
  1、更换User-Agent:可以在每个请求中使用不同的User-Agent字段,避免与其他请求相同IP和头部参数给网站接口留下“爬虫”的印象。 
  2、设置合理的间隔时间:通过设置适当间隔(如访问网站后1-5秒内不再访问),以模拟真实用户的行为,减少被检测到的概率。 
  3、使用代理IP:代理IP可以隐藏你的真实IP地址,但是如果时间较长或请求次数太频繁,代理IP也有被风控的危险,所以尽量使用更多,质量更好的IP池。 以下是一段使用代理IP的Selenium爬虫示例代码,可以在每次请求时更换一个随机代理IP,这种就是隧道转发模式的代理,需要注意的是,要使用合法、高质量的代理IP服务提供商比如亿牛云代理,以避免安全和质量问题。
  from selenium import webdriver
      import string
      import zipfile
      # 代理服务器(产品官网 www.16yun.cn)
      proxyHost = "t.16yun.cn"
      proxyPort = "3111"
      # 代理验证信息
      proxyUser = "username"
      proxyPass = "password"
      def create_proxy_auth_extension(proxy_host, proxy_port,
                                      proxy_username, proxy_password,
                                      scheme='http', plugin_path=None):
          if plugin_path is None:
              plugin_path = r'/tmp/{}_{}@t.16yun.zip'.format(proxy_username, proxy_password)
          manifest_json = """
          {
              "version": "1.0.0",
              "manifest_version": 2,
              "name": "16YUN Proxy",
              "permissions": [
                  "proxy",
                  "tabs",
                  "unlimitedStorage",
                  "storage",
                  "<all_urls>",
                  "webRequest",
                  "webRequestBlocking"
              ],
              "background": {
                  "scripts": ["background.js"]
              },
              "minimum_chrome_version":"22.0.0"
          }
          """
          background_js = string.Template(
              """
              var config = {
                  mode: "fixed_servers",
                  rules: {
                      singleProxy: {
                          scheme: "${scheme}",
                          host: "${host}",
                          port: parseInt(${port})
                      },
                      bypassList: ["localhost"]
                  }
                };
              chrome.proxy.settings.set({value: config, scope: "regular"}, function() {});
              function callbackFn(details) {
                  return {
                      authCredentials: {
                          username: "${username}",
                          password: "${password}"
                      }
                  };
              }
              chrome.webRequest.onAuthRequired.addListener(
                  callbackFn,
                  {urls: ["<all_urls>"]},
                  ['blocking']
              );
              """
          ).substitute(
              host=proxy_host,
              port=proxy_port,
              username=proxy_username,
              password=proxy_password,
              scheme=scheme,
          )
          print(background_js)
          with zipfile.ZipFile(plugin_path, 'w') as zp:
              zp.writestr("manifest.json", manifest_json)
              zp.writestr("background.js", background_js)
          return plugin_path
      proxy_auth_plugin_path = create_proxy_auth_extension(
          proxy_host=proxyHost,
          proxy_port=proxyPort,
          proxy_username=proxyUser,
          proxy_password=proxyPass)
      option = webdriver.ChromeOptions()
      option.add_argument("--start-maximized")
      # 如报错 chrome-extensions
      # option.add_argument("--disable-extensions")
      option.add_extension(proxy_auth_plugin_path)
      # 关闭webdriver的一些标志
      # option.add_experimental_option('excludeSwitches', ['enable-automation'])
      driver = webdriver.Chrome(
          chrome_options=option,
          executable_path="./chromdriver"
      )
      # 修改webdriver get属性
      # script = '''
      # Object.defineProperty(navigator, 'webdriver', {
      # get: () => undefined
      # })
      # '''
      # driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {"source": script})
      driver.get("https://httpbin.org/ip")
  本文内容不用于商业目的,如涉及知识产权问题,请权利人联系51Testing小编(021-64471599-8017),我们将立即处理
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号