使用selenium登录到stackoverflow可以,但是不能使用scrapy python如何通过无头浏览登录?

问题描述

我一直在尝试自动登录到stackoverflow以学习Web抓取。首先,我尝试了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)

因此,我稍后尝试了硒,我使用以下代码成功登录了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()

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

那么,有什么办法可以解决scrapy中的登录问题。或者,我可以将硒与scrapy合并,这样我就可以与硒进行登录,然后可以通过scrapy完成其余工作了?

解决方法

  • robots.txt似乎禁止使用https://stackoverflow.com/users/login网址,因此我不确定stackoverflow允许自动执行此操作
  • 您不需要Selenium登录。您可以为此使用Scrapy。我基于他们官方的documentation中的示例。您可以使用FromRequest.from_response填充登录所需的大多数字段,只需添加正确的电子邮件和密码即可。以下内容适用于我在易碎外壳中使用:
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)
,

除了Wim Hermans的方法外,您还可以POST https://stackoverflow.com/users/login使用以下参数:

  • email:您的电子邮件地址
  • password:您的密码
  • fkey

这是一个例子:

import requests
import getpass
from pyquery import PyQuery

# Fetch the fkey
login_page = requests.get('https://stackoverflow.com/users/login').text
pq = PyQuery(login_page)
fkey = pq('input[name="fkey"]').val()

# Prompt for email and password
email = input("Email: ")
password = getpass.getpass()

# Login
requests.post(
    'https://stackoverflow.com/users/login',data = {
        'email': email,'password': password,'fkey': fkey
    })

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...