首页 > 解决方案 > 使用 selenium 登录到 stackoverflow 是有效的,但使用 scrapy python 不是。如何使用无头浏览登录?

问题描述

我一直在尝试自动登录到 stackoverflow 来学习网络抓取。首先我尝试了scrapy,使用以下代码我没有从中获得那么幸运。

import scrapy
from scrapy.utils.response import open_in_browser

class QuoteSpider(scrapy.Spider):
    name = 'stackoverflow'
    start_urls = ['https://stackoverflow.com/users/login']


    def parse(self, response):
        token = response.xpath('.//*[@name="fkey"]/@value').extract_first()
        yield scrapy.FormRequest('https://stackoverflow.com/users/login?ssrc=head&returnurl=https://stackoverflow.com/',
        formdata = {
            'fkey': token,
            "ssrc": "head",
            'username': "example@gmail.com",
            'password': 'example123',
            'oauth_version':'',
            'oauth_server':''
        },callback=self.startscraper)
    
    def startscraper(self,response):
        yield scrapy.Request('https://stackoverflow.com/users/12454709/gopal-kisi',callback=self.verifylogin)

    def verifylogin(self,response):
        open_in_browser(response)

所以,我后来尝试了 selenium,我使用以下代码成功登录到 stackoverflow。

from selenium import webdriver
import pandas as pd
import time

driver = webdriver.Chrome("./chromedriver.exe")
driver.get("https://stackoverflow.com/users/login?ssrc=head&returnurl=https%3a%2f%2fstackoverflow.com%2f")
time.sleep(2)
username = driver.find_element_by_xpath("//*[@id='email']")
username.clear()
username.send_keys("example@gmail.com")
time.sleep(5)
password = driver.find_element_by_xpath("//*[@id='password']")
password.clear()
password.send_keys("example123")
time.sleep(0.5)
driver.find_element_by_xpath("//*[@id='submit-button']").click()
driver.close()

我知道 selenim 和 scrapy 是两种不同的方法。现在,对于抓取,我发现 scrapy 比 selenium 更容易处理和保存数据,而且它使用无头浏览,就像我需要的那样。

那么,有什么办法可以解决scrapy中的登录问题。或者,我可以将 selenium 与 scrapy 合并,这样,我可以使用 selenium 登录,然后剩余的工作可以由 scrapy 完成?

标签: pythonseleniumauthenticationscrapystackexchange

解决方案


  • 似乎 url https://stackoverflow.com/users/login被 robots.txt 禁止,所以我不确定 stackoverflow 是否允许自动执行此操作
  • 你不需要 Selenium 来登录。你可以使用 Scrapy 来做这个。我以他们官方文档中的示例为基础。您可以使用 FromRequest.from_response 填充登录所需的大部分字段,只需添加正确的电子邮件和密码。以下在scrapy shell中对我有用:
from scrapy import FormRequest

url = "https://stackoverflow.com/users/login"
fetch(url)
req = FormRequest.from_response(
    response,
    formid='login-form',
    formdata={'email': 'test@test.com',
              'password': 'testpw'},
    clickdata={'id': 'submit-button'},
)
fetch(req)

推荐阅读