【问题标题】:Response 403 with Selenium web scraper - how to fix?使用 Selenium web scraper 响应 403 - 如何修复?
【发布时间】:2021-11-11 20:07:45
【问题描述】:

我有一个简单的网络爬虫(在 ubuntu 上使用 selenium 在 chrome-headless 模式下进行爬取),它遍历相同的页面以获取一些信息:

#set driver options
chrome_options = Options()
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--window-size=1420,1080')
chrome_options.add_argument('--headless')
chrome_options.add_argument("--disable-features=VizDisplayCompositor");
chrome_options.add_argument('--disable-dev-shm-usage')
chrome_options.add_argument('--disable-gpu')
chrome_options.add_argument("--disable-notifications")
chrome_options.add_argument("--remote-debugging-port=9222")
chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"])
chrome_options.add_experimental_option('useAutomationExtension', False)
chrome_options.binary_location='/usr/bin/google-chrome-stable'
chrome_driver_binary = "/usr/bin/chromedriver"
driver = webdriver.Chrome(executable_path=chrome_driver_binary, chrome_options=chrome_options)

#Set base url 
base_url = 'www.example.com&page='


events = []
eventContainerBucket = []

for i in range(1,30):

    #cycle through pages in range
    driver.get(base_url + str(i))
    pageURL = base_url + str(i)

    # get events links
    event_list = driver.find_elements_by_css_selector('div[class^=_1abc] a[class^=_1xyz]')
    # collect href attribute of events in even_list
    events.extend(list(event.get_attribute("href") for event in event_list))

print("total events: ", (len(events)))

#GET request user-agent
headers = {'User-Agent': "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36"}


# iterate through all events and open them.
item = {}
allEvents = []
for event in events:

    try:
        driver.get(event)
        currentUrl = driver.current_url
        print(currentUrl)
    except TimeoutException as ex:
        print(ex.Message)
        webDriver.navigate().refresh()


    try:
        currentRequest = requests.get(currentUrl, headers=headers)
        print (currentRequest)

        #print currentRequest.status_code
    except requests.exceptions.RequestException as e:
        print(e)
        continue

我的问题:

直到昨天,当我开始收到 403 错误时,一切都运行良好。通常,该脚本将遍历大约 20-30 个 url 没问题,但它会给我一个 403 响应。

我的尝试:

尝试将请求标头更改为:

headers={'User-Agent': 'Mozilla/5.0'})

仍然收到 403。我需要为驱动程序添加等待时间吗?谢谢。

【问题讨论】:

  • 尝试复制您使用的浏览器中的所有标题,而不仅仅是用户代理。
  • 我怎样才能得到标题?我在 chrome-headless 中使用 selenium,在 ubuntu 中...

标签: python selenium-webdriver python-requests selenium-chromedriver http-headers


【解决方案1】:

403 表示您的请求已被服务器拒绝。虽然无法访问实际网站就无法准确猜测问题出在哪里,但我建议尽可能让请求看起来像人类一样。

您需要确保在无头硒中使用的标头与您在访问网站时(自动)发送的标头相匹配。请按以下步骤操作:

  1. 从浏览器手动访问网站
  2. 检查网络请求。在 Chrome 中,您按 F12 或 Ctrl+Shift+I 并选择“网络”选项卡,然后浏览/重新加载您要访问的页面
  3. 将请求复制到pageURL 作为 curl 命令,然后提取-H 标头
  4. 将这些放在您的代码中,如下所示:
headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36',
         'custom-header': 'custom value',
         'cookie': '__cf_bm=some_random_value;'
}

也有可能是您的 IP 地址被屏蔽了,在这种情况下,您应该尝试如下代理:

PROXY = "1.111.111.1:8080" #your proxy

chrome_options = WebDriverWait.ChromeOptions()
chrome_options.add_argument('--proxy-server=%s' % PROXY)

【讨论】:

  • 非常感谢。我将首先尝试标题解决方案。奇怪的是:我似乎并没有被完全阻止——我可以在它失败之前遍历多个 url。刚才,在可能 100 个 url 之后,它给了我, urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='127.0.0.1', port=53253): Max retries exceeded with url
  • 添加一个 driver.implicitly_wait(3) 似乎有帮助,因为它增加了我在出错之前可以迭代的 url 数量。我希望我没有被完全阻止 - 似乎我在经过一定数量的请求后被阻止但没有完全被阻止?
  • 那么似乎是速率限制问题,也许您也可以尝试通过将代理添加到列表中并遍历每个 n 请求来轮换代理 @DiamondJoe12
  • 代理究竟从何而来?即 PROXY = "1.111.111.1:8080" 我需要从某个地方分配这个吗?这是一个在 ubuntu 上运行的 python 脚本。
  • 仅包含所有请求标头。而且我不知道为什么开发人员选择 403 而不是 429,但从你所描述的情况来看,这是一个速率限制问题。 @DiamondJoe12
猜你喜欢
  • 2020-06-04
  • 2016-10-14
  • 2019-11-03
  • 1970-01-01
  • 2019-12-16
  • 2013-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多