XPath和Scrapy - 当标签的深度和数量不一致时刮擦链接

时间:2017-09-16 21:16:05

标签: python xpath scrapy

我正在使用Scrapy的SitemapSpider浏览Shopify商店列表。我正在使用XPath从各自的集合中提取所有产品。通常,这不是很难做到的。但是,集合页面的html在几个方面因站点而异。我将尝试总结一些必要的观点,以了解我到底想要做什么:

  • 所有产品链接都在div元素
  • 我的标签所具有的div祖先数量不一致
  • div元素内标签的深度不一致
  • 在div元素中可以有一个或两个包含href的标签。它因站点而异。如果有两个则相同
  • div元素的类名不一致,所以为了简单起见,我删除了它们

所以包含我想要的产品链接的代码可以在div元素中有多个标签,其深度不一致,如下所示:



<!-- Product One -->

<div>
  <div>
    <div>
      <a href="/product_1">
      </a>
      
    </div>

    <a href="/product_1">
    </a>
  </div>
</div>

<!-- Product Two -->

<div>
  <div>
    <div>
      <a href="/product_2">
      </a>
      
    </div>

    <a href="/product_2">
    </a>
  </div>
</div>

<!-- Product Three-->

<div>
  <div>
    <div>
      <a href="/product_3">
      </a>
      
    </div>

    <a href="/product_3">
    </a>
  </div>
</div>
&#13;
&#13;
&#13;

或者它可以在光谱的完全相反的一端,在一个深度为1的div元素中有一个标记,如下所示:

&#13;
&#13;
<div>
  <a href="/product_1">
  </a>
  
</div>

<div>
  <a href="/product_2">
  </a>
 
</div>

<div>
  <a href="/product_3">
  </a>
  
</div>
&#13;
&#13;
&#13;

所以我想我会选择第一个包含关键字&#34; product&#34;的标签的div元素,只从div元素中的第一个标签中提取href。

&#13;
&#13;
    <div> <!-- I want to select this div element -->
      <div>
        <div>
          <a href="/product_1">
          </a>
          
        </div>

        <a href="/product_1">
        </a>
      </div>
    </div>
&#13;
&#13;
&#13;

我现在的代码如下:

product_links = response.xpath('//div//a[contains(@href, "product")][1]/@href').extract()

我仍然收到重复的值,但显然它没有按照我的意愿行事。

如果有人真正阅读了所有内容,那么绝对会有任何帮助!

1 个答案:

答案 0 :(得分:0)

由于您的问题主要是在响应中重复,请将Fish转换为age。这给出了所有数据的单个实例。

不使用set:

class Fish {
    int numberOfFins;
    int age;
    public Fish(int age) {
        this.age = age;         // Sets Fish#age
    }
}

public class Shark extends Fish {
    private int age;

    public Shark(int age) {
        super(age);
        this.age = age * 2;     // Sets Shark#age
    }

    public static void main(String[] args) {
        Shark s = new Shark(10);
        Fish f = s;
        System.out.println(f.age); // 10
        System.out.println(s.age); // 20
    }
}

使用-g

-parameters

假设问题仅针对 response,那么最好的方法是使用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

之前:

>>> set(response.xpath('//div//a[contains(@href, "product")]/@href').extract())
set([u'/product_3', u'/product_2', u'/product_1'])

所以,它应该是:

div