【问题标题】:How to avoid a bot detection and scrape a website using python?如何避免机器人检测并使用 python 抓取网站?
【发布时间】:2021-10-23 23:31:16
【问题描述】:

我的问题:

我想抓取以下网站:https://www.coches.net/segunda-mano/。 但是每次我用 python selenium 打开它时,我都会收到消息,他们检测到我是一个机器人。 我怎样才能绕过这个检测? 首先,我尝试了使用 selenium 的简单代码:

from selenium import webdriver
from bs4 import BeautifulSoup

browser = webdriver.Chrome('C:/Python38/chromedriver.exe')
URL = 'https://www.coches.net/segunda-mano/'
browser.get(URL)

然后我用请求尝试了它,但我也不起作用。

from selenium import webdriver
from bs4 import BeautifulSoup

from fake_useragent import UserAgent

import requests

ua = UserAgent()

headers = {"UserAgent":ua.random}

URL = 'https://www.coches.net/segunda-mano/'
r = requests.get(URL, headers = headers)

print(r.statuscode)

在这种情况下,我收到消息 403 = 状态代码,说明禁止访问该 URL。

不知道如何在不被阻止的情况下访问此网页。我将非常感谢您的帮助。提前致谢。

【问题讨论】:

  • 考虑对解决您问题的答案进行投票并将其标记为已完成。

标签: python selenium web-scraping python-requests bots


【解决方案1】:

Selenium 很容易被检测到,尤其是所有主要的反僵尸程序提供商(Cloudflare、Akamai 等)。

为什么?

  1. Selenium 和大多数其他主要 Web 驱动程序将名为 navigator.webdriver 的浏览器变量(网站可以访问)设置为 true。您可以通过前往 Google Chrome 控制台并运行 console.log(navigator.webdriver) 自行检查。如果您使用的是普通浏览器,则为 false。

  2. 用户代理,通常所有设备都有所谓的“用户代理”,这是指访问网站的设备。 Selenium 的用户代理看起来像这样:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/59.0.3071.115 Safari/537.36。你抓到了吗?包含HeadlessChrome,这是另一种检测途径。

这些只是检测 Selenium 浏览器的多种方法中的两种,我强烈建议您阅读 thisthis

最后,如果您想要一个简单、直接的解决方案来绕过检测,它几乎实现了我们讨论过的所有这些概念,我建议您使用undetected-chromedriver。这是一个开源项目,它尽最大努力让您的 Selenium chromedriver 看起来像人类。

【讨论】:

    【解决方案2】:

    我认为您的问题不是机器人检测。您不能只使用requests 从该页面获取结果,因为它会在后台发出 XHR 请求。所以你必须使用 Selenium、splash 等,但在这种情况下似乎是不可能的。

    但是,如果您在页面中进行一些研究,您可以找到在幕后请求哪个 url 来显示结果。我做了那个研究,发现了这个页面(https://ms-mt--api-web.spain.advgo.net/search),它返回一个 json,所以它可以简化你的解析工作。使用 chrome 开发工具,我得到了 curl 请求,只需将其映射到 python 请求并获取此代码:

    import json
    import requests
    
    headers = {
        'authority': 'ms-mt--api-web.spain.advgo.net',
        'sec-ch-ua': '" Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"',
        'accept': 'application/json, text/plain, */*',
        'x-adevinta-channel': 'web-desktop',
        'x-schibsted-tenant': 'coches',
        'sec-ch-ua-mobile': '?0',
        'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36',
        'content-type': 'application/json;charset=UTF-8',
        'origin': 'https://www.coches.net',
        'sec-fetch-site': 'cross-site',
        'sec-fetch-mode': 'cors',
        'sec-fetch-dest': 'empty',
        'referer': 'https://www.coches.net/',
        'accept-language': 'en-US,en;q=0.9,es;q=0.8',
    }
    
    data = '{"pagination":{"page":1,"size":30},"sort":{"order":"desc","term":"relevance"},"filters":{"categories":{"category1Ids":[2500]},"offerTypeIds":[0,2,3,4,5],"isFinanced":false,"price":{"from":null,"to":null},"year":{"from":null,"to":null},"km":{"from":null,"to":null},"provinceIds":[],"fuelTypeIds":[],"bodyTypeIds":[],"doors":[],"seats":[],"transmissionTypeId":0,"hp":{"from":null,"to":null},"sellerTypeId":0,"hasWarranty":null,"isCertified":false,"luggageCapacity":{"from":null,"to":null},"contractId":0}}'
    
    
    while True:
        response = requests.post('https://ms-mt--api-web.spain.advgo.net/search', headers=headers, data=data).json()
        # you should parse items here.
        print(response)
        if not response["items"]:
            break
        data_dict = json.loads(data)
        data_dict["pagination"]["page"] = data_dict["pagination"]["page"]+1 # get the next page.
        data = json.dumps(data_dict)
    
    

    可能有很多不必要的标题和正文信息,您可以编写代码和测试来改进它。

    【讨论】:

      猜你喜欢
      • 2023-03-03
      • 2017-06-09
      • 2018-06-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-18
      • 2021-04-17
      • 1970-01-01
      相关资源
      最近更新 更多