Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/silverlight/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 当标记的深度和数量不一致时,XPath和Scrapy-Scraping链接_Python_Xpath_Scrapy - Fatal编程技术网

Python 当标记的深度和数量不一致时,XPath和Scrapy-Scraping链接

Python 当标记的深度和数量不一致时,XPath和Scrapy-Scraping链接,python,xpath,scrapy,Python,Xpath,Scrapy,我正在使用Scrapy的SitemapSpider浏览Shopify商店的列表。我使用XPath从各自的集合中提取所有产品。通常,这并不难做到。然而,集合页面的html在不同的站点上有两种不同的方式。我将尝试总结一些必要的要点,以了解我到底在做什么: 所有产品链接都在div元素中 我的a标记具有的div祖先数不一致 div元素中标记的深度不一致 div元素中可以有一个或两个a标记包含href。它因地点而异。如果有两个,它们将是相同的 div元素的类名不一致,因此为了简单起见,我删除了它们 因

我正在使用Scrapy的SitemapSpider浏览Shopify商店的列表。我使用XPath从各自的集合中提取所有产品。通常,这并不难做到。然而,集合页面的html在不同的站点上有两种不同的方式。我将尝试总结一些必要的要点,以了解我到底在做什么:

  • 所有产品链接都在div元素中
  • 我的a标记具有的div祖先数不一致
  • div元素中标记的深度不一致
  • div元素中可以有一个或两个a标记包含href。它因地点而异。如果有两个,它们将是相同的
  • div元素的类名不一致,因此为了简单起见,我删除了它们
因此,包含所需产品链接的代码在div元素中可以有多个a标记,深度不一致,如下所示:


由于您的问题主要是在响应中存在重复的,请将
响应
转换为
集合
。这将提供所有数据的单个实例

不使用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