我正在尝试用Scrapy擦拭 - www.paytm.com。该网站使用XAX形式的AJAX请求来显示搜索结果。
我设法追踪XHR,而AJAX响应与JSON类似,但实际上并不是JSON。
这是XHR请求之一的链接 - https://search.paytm.com/search/?page_count=2&userQuery=tv&items_per_page=30&resolution=960x720&quality=high&q=tv&cat_tree=1&callback=angular.callbacks._6。如果您正确地看到了URL,则参数 - page_count - 负责显示不同的结果页面,参数 - userQuery - 负责传递的搜索查询到网站。
现在,如果您正确看到响应。它实际上不是JSON,只是看起来类似于JSON(我在http://jsonlint.com/上进行了修改)。我想用SCRAPY 来擦除它(SCRAPY只是因为它是一个框架,它会比使用像BeautifulSoup这样的其他库更快,因为使用它们来创建一个以如此高的速度进行刮擦的刮刀需要花费很多精力 - 这是我想使用Scrapy的唯一原因。)。
现在,这是我的代码片段,我曾经从URL中提取JSON响应 - :
jsonresponse = json.loads(response.body_as_unicode())
print json.dumps(jsonresponse, indent=4, sort_keys=True)
在执行代码时,它会引发错误声明 - :
2015-07-05 12:13:23 [scrapy] INFO: Scrapy 1.0.0 started (bot: scrapybot)
2015-07-05 12:13:23 [scrapy] INFO: Optional features available: ssl, http11
2015-07-05 12:13:23 [scrapy] INFO: Overridden settings: {'DEPTH_PRIORITY': 1, 'SCHEDULER_MEMORY_QUEUE': 'scrapy.squeues.FifoMemoryQueue', 'SCHEDULER_DISK_QUEUE': 'scrapy.squeues.PickleFifoDiskQueue', 'CONCURRENT_REQUESTS': 100}
2015-07-05 12:13:23 [scrapy] INFO: Enabled extensions: CloseSpider, TelnetConsole, LogStats, CoreStats, SpiderState
2015-07-05 12:13:23 [scrapy] INFO: Enabled downloader middlewares: HttpAuthMiddleware, DownloadTimeoutMiddleware, UserAgentMiddleware, RetryMiddleware, DefaultHeadersMiddleware, MetaRefreshMiddleware, HttpCompressionMiddleware, RedirectMiddleware, CookiesMiddleware, ChunkedTransferMiddleware, DownloaderStats
2015-07-05 12:13:23 [scrapy] INFO: Enabled spider middlewares: HttpErrorMiddleware, OffsiteMiddleware, RefererMiddleware, UrlLengthMiddleware, DepthMiddleware
2015-07-05 12:13:23 [scrapy] INFO: Enabled item pipelines:
2015-07-05 12:13:23 [scrapy] INFO: Spider opened
2015-07-05 12:13:23 [scrapy] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min)
2015-07-05 12:13:23 [scrapy] DEBUG: Telnet console listening on 127.0.0.1:6023
2015-07-05 12:13:24 [scrapy] DEBUG: Crawled (200) <GET https://search.paytm.com/search/?page_count=2&userQuery=tv&items_per_page=30&resolution=960x720&quality=high&q=tv&cat_tree=1&callback=angular.callbacks._6> (referer: None)
2015-07-05 12:13:24 [scrapy] ERROR: Spider error processing <GET https://search.paytm.com/search/?page_count=2&userQuery=tv&items_per_page=30&resolution=960x720&quality=high&q=tv&cat_tree=1&callback=angular.callbacks._6> (referer: None)
Traceback (most recent call last):
File "/usr/lib/python2.7/dist-packages/twisted/internet/defer.py", line 577, in _runCallbacks
current.result = callback(current.result, *args, **kw)
File "Startup App/SCRAPERS/paytmscraper_scrapy/paytmspiderscript.py", line 111, in parse
jsonresponse = json.loads(response.body_as_unicode())
File "/usr/lib/python2.7/json/__init__.py", line 338, in loads
return _default_decoder.decode(s)
File "/usr/lib/python2.7/json/decoder.py", line 366, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/lib/python2.7/json/decoder.py", line 384, in raw_decode
raise ValueError("No JSON object could be decoded")
ValueError: No JSON object could be decoded
2015-07-05 12:13:24 [scrapy] INFO: Closing spider (finished)
2015-07-05 12:13:24 [scrapy] INFO: Dumping Scrapy stats:
{'downloader/request_bytes': 343,
'downloader/request_count': 1,
'downloader/request_method_count/GET': 1,
'downloader/response_bytes': 6483,
'downloader/response_count': 1,
'downloader/response_status_count/200': 1,
'finish_reason': 'finished',
'finish_time': datetime.datetime(2015, 7, 5, 6, 43, 24, 733187),
'log_count/DEBUG': 2,
'log_count/ERROR': 1,
'log_count/INFO': 7,
'response_received_count': 1,
'scheduler/dequeued': 1,
'scheduler/dequeued/memory': 1,
'scheduler/enqueued': 1,
'scheduler/enqueued/memory': 1,
'spider_exceptions/ValueError': 1,
'start_time': datetime.datetime(2015, 7, 5, 6, 43, 23, 908135)}
2015-07-05 12:13:24 [scrapy] INFO: Spider closed (finished)
现在,我的问题,我如何使用Scrapy刮掉这样的反应?如果需要任何其他代码,请随时在评论中提问。我愿意给它!
请提供与此相关的完整代码。非常感谢!也许对JSON Response的某些操作(来自python)(类似于字符串比较)也适用于我,如果它可以帮我刮掉它!
P.S:我不能每次手动(使用手动)修改JSON响应,因为这是网站给出的响应。所以,请建议采用程序化(pythonic)方式。最好,我想用Scrapy作为我的框架。
答案 0 :(得分:3)
如果你看一下not-JSON结果,很明显它包含一个JSON。
如果您从响应中删除了typeof angular.callbacks._6 === "function" && angular.callbacks._6(
初始部分和);
,那么您将获得一个可以使用JSONLint验证的有效JSON。
最终解决方案是在响应中分别找到{
和}
的第一个和最后一个,并提取内部的文本(包括那些大括号)并将其用于{{1而不是整个结果。
答案 1 :(得分:2)
Paytm提供json数据,请检查
https://catalog.paytm.com/v1//g/electronics/mobile-accessories/mobiles
目录页面返回.json数据,包括产品名称,产品网址,报价,实际价格和图像数据等。
如何获取类别的数据:
在上面的网址中你可以看到catalog.paytm.com/v1//g/,它是所有网址的通用名称,你需要用以下格式替换网址的其他部分。
菜单项&gt;类别&gt;子类别。
其中电子是菜单项目,移动配件是类别,手机是移动配件的子类别。
当您以上述格式运行url时,paytm将返回json数据,您可以使用以下参数查询paytm以获取更多页面。
page_count和items_per_count
示例:catalog.paytm.com/v1//g/electronics/mobile-accessories/mobiles?page_count=2&items_per_count=30
在json数据中搜索grid_layout,如果它不可用,页面没有项目,你可以退出循环,否则处理json数据并阅读产品细节。
答案 2 :(得分:0)
变化:
https://search.paytm.com/search/?page_count=2&userQuery=tv&items_per_page=30&resolution=960x720&quality=high&q=tv&cat_tree=1&callback=angular.callbacks._6
为:
https://search.paytm.com/search/?page_count=2&userQuery=tv&items_per_page=30&resolution=960x720&quality=high&q=tv&cat_tree=1
..你有JSON。