在 Scrapy 中发送帖子请求

Posted

技术标签:

【中文标题】在 Scrapy 中发送帖子请求【英文标题】:Send Post Request in Scrapy 【发布时间】:2015-08-01 06:17:27 【问题描述】:

我正在尝试从 google play store 抓取最新评论,并获取我需要发出发布请求的信息。

使用 Postman,它可以工作,并且我得到了想要的响应。

但是终端中的发布请求给了我一个服务器错误

例如:本页https://play.google.com/store/apps/details?id=com.supercell.boombeach

curl -H "Content-Type: application/json" -X POST -d '"id": "com.supercell.boombeach", "reviewType": '0', "reviewSortOrder": '0', "pageNum":'0'' https://play.google.com/store/getreviews

给出一个服务器错误并且

Scrapy 只是忽略了这一行:

frmdata = "id": "com.supercell.boombeach", "reviewType": 0, "reviewSortOrder": 0, "pageNum":0
        url = "https://play.google.com/store/getreviews"
        yield Request(url, callback=self.parse, method="POST", body=urllib.urlencode(frmdata))

【问题讨论】:

【参考方案1】:

上面的答案并没有真正解决问题。他们将数据作为参数而不是 JSON 数据作为请求正文发送。

来自http://bajiecc.cc/questions/1135255/scrapy-formrequest-sending-json:

my_data = 'field1': 'value1', 'field2': 'value2'
request = scrapy.Request( url, method='POST', 
                          body=json.dumps(my_data), 
                          headers='Content-Type':'application/json' )

【讨论】:

如何获取请求正文结果?我使用request.body 它返回我的表单数据... 如果你想要请求的结果,你必须从响应中得到它。 scrapy.Request 可以有一个 'callback' 参数,如果请求被屈服('yield request')并且收到响应,它将被调用。要读取回调函数中的数据(例如:'def parse_entry(self, response)'),只需执行 response.body。我使用了 'jsonresponse = json.loads(response.body_as_unicode())' 因为我得到了一个 json【参考方案2】:

确保formdata 中的每个元素都是字符串/unicode 类型

frmdata = "id": "com.supercell.boombeach", "reviewType": '0', "reviewSortOrder": '0', "pageNum":'0'
url = "https://play.google.com/store/getreviews"
yield FormRequest(url, callback=self.parse, formdata=frmdata)

我觉得这样就可以了

In [1]: from scrapy.http import FormRequest

In [2]: frmdata = "id": "com.supercell.boombeach", "reviewType": '0', "reviewSortOrder": '0', "pageNum":'0'

In [3]: url = "https://play.google.com/store/getreviews"

In [4]: r = FormRequest(url, formdata=frmdata)

In [5]: fetch(r)
 2015-05-20 14:40:09+0530 [default] DEBUG: Crawled (200) <POST      https://play.google.com/store/getreviews> (referer: None)
[s] Available Scrapy objects:
[s]   crawler    <scrapy.crawler.Crawler object at 0x7f3ea4258890>
[s]   item       
[s]   r          <POST https://play.google.com/store/getreviews>
[s]   request    <POST https://play.google.com/store/getreviews>
[s]   response   <200 https://play.google.com/store/getreviews>
[s]   settings   <scrapy.settings.Settings object at 0x7f3eaa205450>
[s]   spider     <Spider 'default' at 0x7f3ea3449cd0>
[s] Useful shortcuts:
[s]   shelp()           Shell help (print this help)
[s]   fetch(req_or_url) Fetch request (or URL) and update local objects
[s]   view(response)    View response in a browser

【讨论】:

谢谢。我仍然无法看到响应数据。如何获得? response.body 将为您提供完整的 html 元素。如果您想获取一些特定条目,可以使用response.xpath(YOUR_XPATH_HERE) 这是我在 r.body 'pageNum=0&id=com.supercell.boombeach&reviewType=0&reviewSortOrder=0' 上得到的结果 你是用 r.body 获取 html 数据吗? 之后我进行了fetch(r) 操作,然后尝试response.body,您一定会得到结果。在您的代码中,您可以直接使用 yield FormRequest(url=url, formdata=frmdata, callback=your_callback_func) 而不是 fetch。我在scrapy shell中测试过,我不能在那里使用回调函数来测试。【参考方案3】:

在 Scrapy 中使用 Post 的示例页面遍历:

def directory_page(self,response):
    if response:
        profiles = response.xpath("//div[@class='heading-h']/h3/a/@href").extract()
        for profile in profiles:
            yield Request(urljoin(response.url,profile),callback=self.profile_collector)

        page = response.meta['page'] + 1
        if page :
            yield FormRequest('https://rotmanconnect.com/AlumniDirectory/getmorerecentjoineduser',
                                        formdata='isSortByName':'false','pageNumber':str(page),
                                        callback= self.directory_page,
                                        meta='page':page)
    else:
         print "No more page available"

【讨论】:

以上是关于在 Scrapy 中发送帖子请求的主要内容,如果未能解决你的问题,请参考以下文章

scrapy发送post请求

Scrapy框架之发送POST请求 򊘮

Scrapy数据建模-构造并发送请求(翻页实现)

python中scrapy怎么发送一个post请求

python爬虫---scrapy框架爬取图片,scrapy手动发送请求,发送post请求,提升爬取效率,请求传参(meta),五大核心组件,中间件

Scrapy 框架 手动发送请求 POST 请求的发送