我正在尝试使用Scrapy从flipp.com/weekly_ads抓取传单。在抓取传单之前,我需要输入区号并搜索本地传单(在网站上,这是通过单击按钮完成的)。
我试图输入一个值,并使用Scrapy模拟“单击按钮”。
最初,我认为我可以使用FormRequest.from_response来搜索表单,并输入我的区号作为值。但是,按钮是用javascript编写的,这意味着找不到表单。
因此,我尝试通过Inspect Element>开发人员工具>网络> XHR找到HTTP调用,以查看是否有任何调用会使用新输入的区号(我的区号)加载等效的flipp页面。
现在,我对Scrapy还是陌生的,并且对HTTP请求/响应非常了解,所以我不确定我找到的链接是否正确(例如,带有新区号的响应)。
这是我发现的请求:
https://gateflipp.flippback.com/bf/flipp/data?locale=en-us&postal_code=90210&sid=10775773055673477
我为请求使用了任意邮政编码(90210)。
我怀疑这是不正确的请求,但是如果我错了,这是正确的:
如何在保持新的区号的同时从此请求导航至-flipp.com/weekly_ads/groceries?
如果这是不正确的:
如何为javascript按钮输入值,并使用Scrapy获得结果?
import scrapy
import requests
import json
class flippSpider(scrapy.Spider):
name = "flippSpider"
postal_code = "M1T2R8"
start_urls = ["https://flipp.com/weekly_ads"]
def parse(self, response): #Input value and simulate button click
return Request() #Find http call to simulate button click with correct field/value parameters
def parse_formrequest(self, response):
yield scrapy.Request("https://flipp.com/weekly_ads/groceries", callback= self.parse_groceries)
def parse_groceries(self, response):
flyers = []
flyer_names = response.css("class.flyer-name").extract()
for flyer_name in flyer_names:
flyer = FlippspiderItem()
flyer["name"] = flyer_name
flyers.append(flyer)
self.log(flyer["name"])
print(flyer_name)
return flyers
我希望在XHR链接中找到实际的javascript按钮请求,但是我发现的请求似乎不正确。
编辑:我不想使用Selenium,它很慢,并且我不想在执行Spider期间弹出浏览器。
答案 0 :(得分:1)
我怀疑这是不正确的请求,但是如果我错了,这是正确的:
这是获取该网站数据所需的正确URL;当您转到flipp.com/weekly_ads/groceries
时在屏幕上看到的内容只是将数据打包为HTML
如何在保持新的区号的同时从此请求导航至-flipp.com/weekly_ads/groceries?
我很确定您问的是错误的问题。您不需要-实际上,导航到flipp.com/weekly_ads/groceries
将100%仍然不执行您想要的操作。您会发现,单击“杂货”时,内容会发生变化,但是浏览器不会导航到任何新页面,也不会发出新的XHR请求。因此,您需要的所有内容都在该JSON中。发生了什么事,他们正在使用包含flyers.*.categories
的{{1}}来缩小返回到与杂货有关的129个传单的范围。
对于“维护新的区号”,这是一个类似的“错误的问题”,因为该XHR返回的每条数据都限定在相关的邮政编码范围内。因此,您无需重新提交任何内容,也不希望您的"Groceries"
请求返回的任何数据都包含postal_code=90210
(或其他任何数据)。
信不信由你,你实际上处在一个绝佳的位置:您无需处理复杂的CSS或XPath查询即可从HTML监狱中释放数据:它们足以为您提供API他们的数据。您只需要处理将内容从其结构分解为自己的内容即可。