python - Scrapy Request 以某种方式切断 URL
问题描述
我喜欢抓取一个如下所示的网址: https ://steamcommunity.com/market/search?appid=730#p1_popular_desc
因为 End 是动态的,所以我在 parse 中创建 url 列表,然后进行请求循环。
问题是,他在 appid=730 之后剪切了 url - 所以每个 url 看起来都一样。如果我切换到 dont_filter=true,我会看到他在 page1 上一次又一次地循环。我没有得到问题:(
代码中的“x”稍后会变得动态(这就是需要 start_url),认为这与问题无关。
似乎他总是从引荐网址中抓取,而不是我给他的那个。网址可能不会以 730 结尾。
调试消息:
...
2019-03-28 23:44:36 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://steamcommunity.com/market/search?appid=730> (referer: None)
2019-03-28 23:44:37 [scrapy.core.engine] DEBUG: Crawled (200) **<GET https://steamcommunity.com/market/search?appid=730#p7_popular_desc> (referer: https://steamcommunity.com/market/search?appid=730)**
...
2019-03-28 23:44:37 [scrapy.core.scraper] DEBUG: Scraped from <200 https://steamcommunity.com/market/search?appid=730>
{'item_count': u'7,899',
'item_name': u'Prisma Case',
'item_price': u'$2.79 USD',
'item_subtext': u'Counter-Strike: Global Offensive'}
2019-03-28 23:44:37 [scrapy.core.scraper] DEBUG: **Scraped from <200 https://steamcommunity.com/market/search?appid=730>**
{'item_count': u'192,519',
'item_name': u'Danger Zone Case',
'item_price': u'$0.30 USD',
'item_subtext': u'Counter-Strike: Global Offensive'}
allowed_domains = ['steamcommunity.com/market']
start_urls = ['https://steamcommunity.com/market/search?appid=730']
def parse(self, response):
x = 15
steam_xpath = [u'//steamcommunity.com/market/search?appid=730#p'+str(i)+'_popular_desc' for i in range(1, x)]
for link in steam_xpath:
yield Request(response.urljoin(link), self.parse_steam, dont_filter=True)
def parse_steam(self, response):
xitem_name = response.xpath('//span[@class="market_listing_item_name"]/text()').extract()
xitem_price = response.xpath('//span[@class="normal_price"]/text()').extract()
xitem_subtext = response.xpath('//span[@class="market_listing_game_name"]/text()').extract()
xitem_count = response.xpath('//span[@class="market_listing_num_listings_qty"]/text()').extract()
for item in zip(xitem_name, xitem_price, xitem_subtext, xitem_count):
new_item = SteammarketItem()
new_item['item_name'] = item[0]
new_item['item_price'] = item[1]
new_item['item_subtext'] = item[2]
new_item['item_count'] = item[3]
yield new_item
预期:150 个结果,循环中每个 url 10 个。
实际:15 个结果,但每个 10 次 - 全部来自第一个 url。
解决方案
地址栏上的 URL 如您所说,但如果您检查浏览器开发人员工具的网络选项卡上的请求,您将看到返回新项目的请求是这样的:
此 Json 包含字段上的页面 HTML,results_html
如果您想使用 xpath 获取数据,可以使用此值创建一个选择器。
import json
def parse(self, response):
data = json.loads(response.text)
sel = scrapy.Selector(text=data['results_html'])
# then use sel
value = sel.xpath('//value').get()
阅读此 URL 的响应,您还可以注意到有一种tip
说法,即也可以&norender=1
在 URL 中添加一个参数,并且根本不使用 HTML。因此,您可以选择最适合自己的方式。
许多网站都这样做,因此您必须密切关注请求,并且不要总是相信地址栏上显示的内容。我建议您永远不要相信“检查器”上出现的内容,并始终检查源代码(右键单击>查看页面源代码)。
推荐阅读
- google-apps-script - 脚本将每日备份工作表快照到其他工作表
- spring - AbstractMongoEventListener 识别更新或添加事件 spring boot mongoDb
- vue.js - 尝试使用 laravel mix 编译时出错
- java - Android Studio 加载源文件不正确(缓存问题?编码问题?)
- javascript - Discord JS 在 message.channel.send 上使用循环
- angular - Input [value] 在里面输入时将其值更改为 undefined
- python - 如何使我刚刚更改的文本居中?
- android - 从应用程序更新云功能中的文档
- json - 在 Swift 中从 JSON 中获取第一个元素(谷歌翻译)
- android - Android Studio - 选择器中无法识别的 state_cheked 属性