【问题标题】:How to submit a form in scrapy?如何在scrapy中提交表单?
【发布时间】:2015-01-20 06:22:38
【问题描述】:

我尝试使用 scrapy 完成登录并收集我的项目提交计数。这是代码。

from scrapy.item import Item, Field
from scrapy.http import FormRequest
from scrapy.spider import Spider
from scrapy.utils.response import open_in_browser


class GitSpider(Spider):
    name = "github"
    allowed_domains = ["github.com"]
    start_urls = ["https://www.github.com/login"]

    def parse(self, response):
        formdata = {'login': 'username',
                'password': 'password' }
        yield FormRequest.from_response(response,
                                        formdata=formdata,
                                        clickdata={'name': 'commit'},
                                        callback=self.parse1)

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

运行代码后

scrapy runspider github.py

它应该向我显示表单的结果页面,这应该是在同一页面中登录失败,因为用户名和密码是假的。但是它向我展示了search page。日志文件位于pastebin

应该如何修复代码?提前致谢。

【问题讨论】:

  • 您介意分享日志结果吗?尝试您的代码时,我注意到 Crawled (301) github.com/login>
  • 这种直接方法无法解决。使用 webdriver 怎么样?

标签: python forms web-scraping scrapy


【解决方案1】:

您的问题是FormRequest.from_response() 使用了不同的表单——“搜索表单”。但是,您希望它改用“登录表单”。提供formnumber 参数:

yield FormRequest.from_response(response,
                                formnumber=1,
                                formdata=formdata,
                                clickdata={'name': 'commit'},
                                callback=self.parse1)

这是我在应用更改后在浏览器中打开的内容(使用“假”用户):

【讨论】:

  • 谢谢你的作品。我查看了官方文档,不知道该表单号是如何工作的。这是链接doc.scrapy.org/en/latest/topics/…
  • @Winston 其实很简单。该页面包含多个表单:第一个(索引为0,默认使用的一个)是搜索表单;第二个 - 是登录表单(索引为1)。 formnumber 让 Scrapy 知道我们对表单号 1 感兴趣。希望能解决问题。
【解决方案2】:

使用 webdriver 的解决方案。

from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
import time
from scrapy.contrib.spiders import CrawlSpider

class GitSpider(CrawlSpider):

    name = "gitscrape"
    allowed_domains = ["github.com"]
    start_urls = ["https://www.github.com/login"]

    def __init__(self):
        self.driver = webdriver.Firefox()

    def parse(self, response):
        self.driver.get(response.url)
        login_form = self.driver.find_element_by_name('login')
        password_form = self.driver.find_element_by_name('password')
        commit = self.driver.find_element_by_name('commit')
        login_form.send_keys("yourlogin")
        password_form.send_keys("yourpassword")
        actions = ActionChains(self.driver)
        actions.click(commit)
        actions.perform()
        # by this point you are logged to github and have access 
        #to all data in the main menù
        time.sleep(3)
        self.driver.close()

【讨论】:

  • 感谢您的代码有效。但只是想知道为什么scrapy 在这个例子中不起作用。我尝试在 delta.com 网站上填写表格,并且成功了。
  • “Scrapy 的有效解决方案” - 您确定您可以使用您提供的代码成功登录吗?
  • 响应 url 打印正确,并使用正确的用户打开 github 页面。你有不同的结果吗?
  • @aberna 是的,我看到在运行您的代码后打印了以下网址:https://github.com/search?utf8=%E2%9C%93&q=&login=yourlogin&password=your+password - 看到它使用搜索表单 - 查看我的答案。谢谢。
  • @alexce 你说得对,scrapy 的解决方案并不完整。你的代码更合适
【解决方案3】:

使用“formname”参数也可以:

yield FormRequest.from_response(response,
                            formname='Login',
                            formdata=formdata,
                            clickdata={'name': 'commit'},
                            callback=self.parse1)

【讨论】:

    猜你喜欢
    • 2018-02-09
    • 1970-01-01
    • 2012-05-25
    • 1970-01-01
    • 2012-05-27
    • 2017-07-24
    • 2012-05-25
    • 2014-10-31
    相关资源
    最近更新 更多