我正在使用scrapy(在PyCharm v2020.1.3上)构建一个爬行这个网页的蜘蛛:“https://www.woolworths.com.au/shop/browse/drinks/cordials-juices-iced-teas/iced-teas“,我想提取产品名称,和breadcrumb在一个列表格式,并将结果保存在一个csv文件。我尝试了以下代码,但它返回空括号[],在我检查了html代码后,我发现内容隐藏在angularjs格式。如果有人有解决方案,这将是伟大的谢谢
import scrapy
class ProductsSpider(scrapy.Spider):
name = 'products'
start_urls = ['https://www.woolworths.com.au/shop/browse/drinks/cordials-juices-iced-teas/iced-teas']
def parse(self, response):
product = response.css('a.shelfProductTile-descriptionLink::text').extract()
yield "productnames"
2条答案
按热度按时间cdmah0mi1#
你不能通过解析HTML得到你想要的产品。它是严重的javascript导向,因此scrapy不会解析它。
获取产品名称最简单的方法,我不知道你所说的breadcrumbs是指重新设计HTTP请求。woolworths网站通过API生成产品详细信息。如果我们可以模仿浏览器发出的获取产品信息的请求,我们就可以以一种漂亮整洁的格式获得信息。
首先,你必须在www.example.com
ROBOTSTXT_OBEY = False
中设置。小心这些数据的长期刮擦,因为你的IP可能会在某个时候被禁止。settings.pyROBOTSTXT_OBEY = False
. Becareful about protracted scrapes of this data because your IP will probably get banned at some point.代码示例
解释
我们从
start_requests
中定义的URL开始。此URL是woolworth用于获取冰茶信息的API的特定URL。对于woolworth上的任何其他链接,/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
。通过预览和在requests中使用json,我们可以看到这些python字典实际上位于一个列表中,因此我们可以使用for循环来循环每个产品,这就是我们在这里所做的。
然后我们生成一个字典来提取数据,
a
指的是每个产品,它是它自己的字典,a['Name']
指的是特定的python字典键'Name',并给我们提供正确的值。为了更好地理解这一点,我总是使用jupyter中的requests包来找出正确的方法来获得我想要的数据。剩下要做的就是使用
scrapy crawl test -o products.csv
将其输出到CSV文件。我真的不能帮助你比这更多,直到你指定任何其他数据,你想从这个页面。请记住,你要对什么网站希望你刮,但也在该网站上的任何其他页面,你将需要找出具体的URL到API获得这些产品。我已经给你这样做的方法,我建议,如果你想自动化这将是值得你的,而试图与此斗争。我们听到帮助,但对你的一部分,你的尝试是如何学习编码。
有关动态内容方法的其他信息
关于这个主题有很多信息。这里有一些指导方针,当你浏览javascript导向的网站时,你应该考虑一下。默认的是你应该尝试重新设计浏览器加载页面信息的请求。这就是本网站和其他许多网站的javascript所做的。它提供了一种动态的方式,无需通过HTTP请求来重新加载页面以显示新信息。如果我们可以模拟该请求,我们可以得到我们想要的信息。这是获得动态内容的最有效的方法。
按优先顺序排列
1.重新设计HTTP请求
1.刮溅
1.刮痧-- selenium
1.将Selenium软件包导入脚本
Scrapy-splash比selenium包稍好一些,因为它预先呈现页面,让您可以访问带有数据的选择器。Selenium速度慢,容易出错,但允许您模拟浏览器活动。
有多种方法可以将 selenium 元素包含到脚本中,请参阅下面的概述。
推荐阅读/研究
1.查看关于动态内容here的零碎文档这将给你一个处理动态内容的步骤的概述。我会说一般来说 selenium 应该被认为是最后的手段。当做更大规模的抓取时,它是相当低效的。
1.如果你正在考虑在脚本中添加selenium包。这可能是让你的脚本工作的较低门槛,但不一定那么有效。在一天结束的时候,scrappy是一个框架,但在添加第三方包方面有很大的灵活性。spider脚本只是一个在后台导入scrappy架构的python类。只要你“如果你注意到了这个问题,并翻译了一些 selenium 元素来使用scrappy,你应该可以在脚本中输入 selenium 元素。我想这个解决方案可能是效率最低的。
1.考虑使用scrapy-splash,splash预渲染页面,并允许您添加javascript执行。Docs是here和scrapinghub here的一篇好文章
avwztpqn2#
在2023年重新审视这个问题。如上所述,使用请求,美丽的汤或scrapy将是这个特定的网站的挑战,因为它的结构。
不过,有一种方法可以绕过这个问题,那就是使用
playwright
package。下面是一个例子,说明如何从页面中提取产品名称、价格和单位成本。“breadcrumbs”可以在脚本中使用相同的概念来提取,您可以抓取包含breadcrumbs的容器并对其进行迭代。
删除headless选项将阻止浏览器在桌面上打开。