【问题标题】:PYTHON SCRAPY Can't POST information to FORMS,PYTHON ScrAPY 无法将信息发布到表单,
【发布时间】:2013-06-28 12:32:27
【问题描述】:

当我在这个问题上苦苦挣扎了几天时,我想我会请求很大的帮助。我尝试了所有可能的(据我所知)方法,但仍然没有结果。我做错了什么,但仍然无法弄清楚它是什么。所以感谢每一位愿意去冒险的人。 第一件事: 我正在尝试使用 POST 方法将信息发布到 delta.com 上的表单 与此网站一样,它很复杂,因为它们涉及会话、cookie 和 Javascript,因此在那里可能会出现问题。 我正在使用在 stackoverflow 中找到的代码示例: Using MultipartPostHandler to POST form-data with Python 这是我为 delta 网页调整的代码。

from scrapy.selector import HtmlXPathSelector
from scrapy.http import FormRequest, Request
from delta.items import DeltaItem
from scrapy.contrib.spiders import CrawlSpider, Rule


class DmozSpider(CrawlSpider):
    name = "delta"
    allowed_domains = ["http://www.delta.com"]
    start_urls = ["http://www.delta.com"]

    def start_requests(self, response):
        yield FormRequest.from_response(response, formname='flightSearchForm',url="http://www.delta.com/booking/findFlights.do", formdata={'departureCity[0]':'JFK', 'destinationCity[0]':'SFO','departureDate[0]':'07.20.2013','departureDate[1]':'07.28.2013','paxCount':'1'},callback=self.parse1)

    def parse1(self, response):
        hxs = HtmlXPathSelector(response)
        sites = hxs.select('//')
        items = []
        for site in sites:
            item = DeltaItem()
            item['title'] = site.select('text()').extract()
            item['link'] = site.select('text()').extract()
            item['desc'] = site.select('text()').extract()
            items.append(item)
        return items

当我指示蜘蛛在终端中爬行时,我看到:

 scrapy crawl delta -o items.xml  -t xml

2013-07-01 13:39:30+0300 [scrapy] INFO: Scrapy 0.16.2 started (bot: delta)
2013-07-01 13:39:30+0300 [scrapy] DEBUG: Enabled extensions: FeedExporter, LogStats, TelnetConsole, CloseSpider, WebService, CoreStats, SpiderState
2013-07-01 13:39:30+0300 [scrapy] DEBUG: Enabled downloader middlewares: HttpAuthMiddleware, DownloadTimeoutMiddleware, UserAgentMiddleware, RetryMiddleware, DefaultHeadersMiddleware, RedirectMiddleware, CookiesMiddleware, HttpCompressionMiddleware, ChunkedTransferMiddleware, DownloaderStats
2013-07-01 13:39:30+0300 [scrapy] DEBUG: Enabled spider middlewares: HttpErrorMiddleware, OffsiteMiddleware, RefererMiddleware, UrlLengthMiddleware, DepthMiddleware
2013-07-01 13:39:30+0300 [scrapy] DEBUG: Enabled item pipelines: 
2013-07-01 13:39:30+0300 [delta] INFO: Spider opened
2013-07-01 13:39:30+0300 [delta] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min)
2013-07-01 13:39:30+0300 [scrapy] DEBUG: Telnet console listening on 0.0.0.0:6023
2013-07-01 13:39:30+0300 [scrapy] DEBUG: Web service listening on 0.0.0.0:6080
2013-07-01 13:39:33+0300 [delta] DEBUG: Crawled (200) <GET http://www.delta.com> (referer: None)
2013-07-01 13:39:33+0300 [delta] INFO: Closing spider (finished)
2013-07-01 13:39:33+0300 [delta] INFO: Dumping Scrapy stats:
    {'downloader/request_bytes': 219,
     'downloader/request_count': 1,
     'downloader/request_method_count/GET': 1,
     'downloader/response_bytes': 27842,
     'downloader/response_count': 1,
     'downloader/response_status_count/200': 1,
     'finish_reason': 'finished',
     'finish_time': datetime.datetime(2013, 7, 1, 10, 39, 33, 159235),
     'log_count/DEBUG': 7,
     'log_count/INFO': 4,
     'response_received_count': 1,
     'scheduler/dequeued': 1,
     'scheduler/dequeued/memory': 1,
     'scheduler/enqueued': 1,
     'scheduler/enqueued/memory': 1,
     'start_time': datetime.datetime(2013, 7, 1, 10, 39, 30, 734090)}
2013-07-01 13:39:33+0300 [delta] INFO: Spider closed (finished)

如果您与链接中的示例进行比较,即使我使用几乎相同的代码,我也看不到我设法制作了 POST 方法。 我什至尝试使用来自 W3schools 的非常简单的 HTML/PHP 表单,我将其放在服务器上,但在那里相同。我从来没有设法创建 POST。 我认为问题很简单,但是因为只有我拥有的 Python 知识是 Scrapy 并且所有 Scrapy 都是我在网上找到的(我有据可查)和示例,但这对我来说仍然不够。因此,如果任何人至少可以展示正确的方式,那将是非常大的帮助。

【问题讨论】:

  • 引用会不会让你发帖,看看引用的robot.txt
  • 嗯...好点,但我使用相同的代码 (w3schools.com/php/php_forms.asp) 来测试我放置在服务器中的表单并且我没有任何 robots.txt 文件。它给了我同样的结果。

标签: python forms post web-scraping scrapy


【解决方案1】:

这是一个将Request.from_response 用于delta.com 的工作示例:

from scrapy.item import Item, Field
from scrapy.http import FormRequest
from scrapy.spider import BaseSpider


class DeltaItem(Item):
    title = Field()
    link = Field()
    desc = Field()


class DmozSpider(BaseSpider):
    name = "delta"
    allowed_domains = ["delta.com"]
    start_urls = ["http://www.delta.com"]

    def parse(self, response):
        yield FormRequest.from_response(response,
                                        formname='flightSearchForm',
                                        formdata={'departureCity[0]': 'JFK',
                                                  'destinationCity[0]': 'SFO',
                                                  'departureDate[0]': '07.20.2013',
                                                  'departureDate[1]': '07.28.2013'},
                                        callback=self.parse1)

    def parse1(self, response):
        print response.status

你使用了错误的爬虫方法,加上 allowed_domains 设置不正确。

但是,无论如何,delta.com 大量使用动态 ajax 调用来加载内容 - 这就是您的问题开始的地方。例如。 parse1 方法中的 response 不包含任何搜索结果 - 而是包含用于加载动态加载结果的 AWAY WE GO. ARRIVING AT YOUR FLIGHTS SOON 页面的 html。

基本上,您应该使用您的浏览器开发人员工具并尝试在您的蜘蛛程序中模拟这些 ajax 调用,或者使用使用真实浏览器的selenium 之类的工具(您可以将它与scrapy 结合使用)。

另见:

希望对您有所帮助。

【讨论】:

  • 谢谢亚历克西。它在 POST 上对我非常有效,并提出了我一直坚持的新问题,但我会尝试自己解决。至少几天。无论如何,你的回答是很大的帮助。而且我没有像样的声誉来相应地评价它。当你在这里时,世界肯定会变得更好......微笑
  • 不客气,谢谢,请随时在单独的线程中询问有关该主题的更多问题。
  • @alecxe 非常感谢您的信息 +1。使用你关于达美航空公司的例子......无论如何都知道(使用scrapy)所有可能的自动完成?在这种情况下,例如机场的确切名称?是否有任何教程或文档可以让我获得此类信息?
  • @DanielTheRocketMan 如果您需要所有可能的机场列表,我会向 wikipedia list of airports 提出请求,并在 python 数据结构中解析机场列表(如果您需要对其进行查找)。
猜你喜欢
  • 2020-11-17
  • 1970-01-01
  • 2021-10-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-20
  • 2018-11-02
相关资源
最近更新 更多