Python 当标记的深度和数量不一致时,XPath和Scrapy-Scraping链接
我正在使用Scrapy的SitemapSpider浏览Shopify商店的列表。我使用XPath从各自的集合中提取所有产品。通常,这并不难做到。然而,集合页面的html在不同的站点上有两种不同的方式。我将尝试总结一些必要的要点,以了解我到底在做什么:Python 当标记的深度和数量不一致时,XPath和Scrapy-Scraping链接,python,xpath,scrapy,Python,Xpath,Scrapy,我正在使用Scrapy的SitemapSpider浏览Shopify商店的列表。我使用XPath从各自的集合中提取所有产品。通常,这并不难做到。然而,集合页面的html在不同的站点上有两种不同的方式。我将尝试总结一些必要的要点,以了解我到底在做什么: 所有产品链接都在div元素中 我的a标记具有的div祖先数不一致 div元素中标记的深度不一致 div元素中可以有一个或两个a标记包含href。它因地点而异。如果有两个,它们将是相同的 div元素的类名不一致,因此为了简单起见,我删除了它们 因
- 所有产品链接都在div元素中
- 我的a标记具有的div祖先数不一致
- div元素中标记的深度不一致
- div元素中可以有一个或两个a标记包含href。它因地点而异。如果有两个,它们将是相同的
- div元素的类名不一致,因此为了简单起见,我删除了它们
由于您的问题主要是在响应中存在重复的,请将
响应
转换为集合
。这将提供所有数据的单个实例
不使用set:
>>> response.xpath('//div//a[contains(@href, "product")]/@href').extract()
[u'/product_1', u'/product_1', u'/product_2', u'/product_2', u'/product_3', u'/product_3']
使用设置:
>>> set(response.xpath('//div//a[contains(@href, "product")]/@href').extract())
set([u'/product_3', u'/product_2', u'/product_1'])
假设问题只针对单个div
,那么最好的方法是使用extract\u first()
命令只提取第一个匹配的元素。使用它的好处是,它避免了索引器
,并且在找不到任何与选择匹配的元素时返回None
之前:
>>> response.xpath('//div//a[contains(@href, "product")]/@href').extract_first()
[u'/product_1', u'/product_1']
因此,它应该是:
>>> response.xpath('//div//a[contains(@href, "product")]/@href').extract_first()
u'/product_1'
在xpath中,您提到了“集合”和“产品”,但示例中只有“产品1”或“产品2”或“产品3”。“collections”从何而来?显然你想要最外层的div,只要至少有一个内部div包含与“/product_”的链接?@BillBell抱歉,我没听清楚我把它放在那里了。由于我正在从集合页面中删除产品链接,因此链接的格式为/collections/collection name/products/product name。我用它来确保我没有得到任何不受欢迎的链接。我现在删除了它以避免混淆。@BillBell是的,我正在尝试选择最外层的div,其中包含带有“product”的链接。我认为正在发生的是,它在每个a标记之前选择最直接的div元素,导致我获得重复的href。使用Set
解决了我的问题。不过要注意的是,在我的脚本中,我获取了所有产品的列表,并使用从每个产品页面获取数据的函数对其进行迭代。由于集合是无序的,当我迭代我的产品链接时,我得到的数据没有特定的顺序,但这没关系,因为我可以使用excel中的标签对我的产品进行排序data@barnesc,是的,使用集合将产生该问题。要缓解这种情况,请使用OrderedSet