您将无法通过解析 HTML 获得所需的产品。它是大量面向 javascript 的,因此 scrapy 不会解析它。
获取产品名称的最简单方法,我不确定您所说的面包屑是什么意思是重新设计 HTTP 请求。 Woolworths 网站通过 API 生成产品详细信息。如果我们可以模仿浏览器为获取产品信息而发出的请求,我们就可以以简洁的格式获取信息。
首先你必须在settings.py中设置ROBOTSTXT_OBEY = False。小心这些数据的长期刮擦,因为您的 IP 可能会在某个时候被禁止。
代码示例
import scrapy
class TestSpider(scrapy.Spider):
name = 'test'
allowed_domains = ['woolworths.com']
data = {
'excludeUnavailable': 'true',
'source': 'RR-Best Sellers'}
def start_requests(self):
url = 'https://www.woolworths.com.au/apis/ui/products/58520,341057,305224,70660,208073,69391,69418,65416,305227,305084,305223,427068,201688,427069,341058,305195,201689,317793,714860,57624'
yield scrapy.Request(url=url,meta=self.data,callback=self.parse)
def parse(self, response):
data = response.json()
for a in data:
yield {
'name': a['Name'],
}
解释
我们从 start_requests 中定义的 URL 开始。此 URL 是 Woolworth 用于获取冰茶信息的 API 的特定 URL。对于 woodworths 上的任何其他链接,/products/ 之后的 URL 部分将特定于网站的该部分。
我们之所以使用它,是因为使用浏览器活动很慢并且容易脆弱。这速度很快,而且我们可以获得的信息通常是高度结构化的,更适合抓取。
那么我们如何获得您可能会询问的 URL?您需要检查页面,并找到正确的请求。如果您单击网络工具,然后重新加载网站。你会看到一堆请求。通常最大的请求是包含所有数据的请求。单击它并单击预览会在右侧为您提供一个框。这提供了产品的所有详细信息。
在下一张图片中,您可以看到产品数据的预览
然后我们可以从该请求中获取请求 URL 和其他任何内容。
我会经常将此请求复制为 CURL(Bash 命令),如此处所示
并将其输入 curl.trillworks.com。这可以将 CURL 转换为 python。为您提供格式良好的标头和模仿请求所需的任何其他数据。
现在把它放到 jupyter 中玩一下,你实际上只需要参数而不是标题,这要好得多。
回到代码。我们做一个请求,使用元参数我们可以传递数据,记住因为它在函数之外我们必须使用self.data,然后指定要解析的回调。
我们可以使用response.json()方法将JSON对象转换为每个产品对应的一组python字典。您必须有 scrapy V2.2 才能使用此方法。其他你可以使用data = json.loads(response.text),但你必须在脚本顶部输入import json。
从预览和使用请求中的 json 我们可以看到这些 python 字典实际上是在一个列表中,因此我们可以使用 for 循环来循环每个产品,这就是我们在这里所做的。
然后我们生成一个字典来提取数据,a 指的是每个产品,它是它自己的字典,a['Name'] 指的是特定的 Python 字典键“名称”并为我们提供正确的值。为了更好地了解这一点,我总是在 jupyter 中使用 requests 包来找出获取我想要的数据的正确方法。
剩下要做的就是使用scrapy crawl test -o products.csv 将其输出到 CSV 文件。
在您指定此页面所需的任何其他数据之前,我真的无法为您提供更多帮助。请记住,您违反了网站希望您抓取的内容,而且该网站上的任何其他页面都需要找出 API 的特定 URL 才能获取这些产品。我已经为您提供了执行此操作的方法,我建议如果您想自动执行此操作,那么尝试与此作斗争是值得的。我们很乐意为您提供帮助,但您可以尝试学习编码的方式。
关于动态内容方法的附加信息
关于这个主题的信息非常丰富。以下是在查看面向 javascript 的网站时要考虑的一些准则。默认情况下,您应该尝试重新设计浏览器为加载页面信息而发出的请求。这就是本网站和许多其他网站中的 javascript 正在做的事情,它提供了一种动态方式,无需重新加载页面即可通过发出 HTTP 请求来显示新信息。如果我们能模仿那个请求,我们就能得到我们想要的信息。这是获取动态内容的最有效方式。
按优先顺序排列
- 重新设计 HTTP 请求
- Scrapy-splash
- Scrapy_selenium
- 将 selenium 包导入到您的脚本中
Scrapy-splash 比 selenium 包稍好,因为它预渲染页面,让您可以访问带有数据的选择器。 Selenium 很慢,容易出错,但可以让您模仿浏览器活动。
有多种方法可以将 selenium 包含到您的脚本中,请参阅下面的概述。
推荐阅读/研究
-
查看关于动态内容的scrapy文档here
这将为您概述处理动态内容的步骤。我会说一般来说硒应该被认为是最后的手段。在进行更大规模的抓取时效率非常低。
-
如果您正在考虑将 selenium 包添加到您的脚本中。这可能是让您的脚本工作的较低门槛,但不一定那么有效。归根结底,scrapy 是一个框架,但在添加 3rd 方包方面有很大的灵活性。蜘蛛脚本只是一个在后台导入scrapy架构的python类。只要您注意响应并翻译一些硒以使用scrapy,您应该能够将硒输入到您的脚本中。我认为这个解决方案可能是效率最低的。
-
考虑使用 scrapy-splash,splash 会预渲染页面并允许您添加 javascript 执行。文档是 here 和来自 scrapinghub here 的一篇好文章
- Scrapy-selenium 是一个带有自定义 scrapy 下载器中间件的软件包,允许您执行 selenium 操作并执行 javascript。 Docs here 你需要尝试一下才能从中获取登录过程,它没有与 selenium 包本身相同的详细程度。