2017-09-16 4 views
2

ScrapyのSitemapSpiderを使用してShopifyストアのリストを表示します。私はすべての製品をそれぞれのコレクションからXPathで取得しています。通常、これはやるのが難しくありません。しかし、コレクションページのhtmlはいくつかの点でサイトごとに異なります。私のタグ(複数可)のdiv祖先の XPathとScrapy - タグの深さと数量が矛盾している場合のリンクの掻き取り

  • 数が持っているすべての製品のリンクはdiv要素内にある

    • :私は私がやろうとしている正確に理解するために必要ないくつかのポイントをまとめてみます矛盾しています
    • div要素内のタグの深さは矛盾しています
    • div要素内にhrefを含むタグが1つまたは2つあります。サイトごとに異なります。 2が存在する場合、それらは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>

    それともジ内部タグの1つを有する、スペクトルの完全な反対側の端部にあることができますVこのようなものの深さにある要素:

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

    は、だから私はからのみのhrefを抽出し、私はキーワード「製品」を含むタグを持っている非常に最初のdiv要素を選択することになる考え出しdiv要素の最初のタグ。

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

    私が持っているコードは、今のようになります。

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

    私はまだそう明らかに私はそれが欲しいものをやっていないのに重複した値を受信して​​います。

    誰もが実際にそれをすべて読んだら、絶対に助けてください!

  • +0

    'product_3' 「コレクション」はどこから来たのですか? –

    +0

    少なくとも1つの内部divに '/ product_'を含むリンクが含まれている限り、最も外側のdivが必要ですか? –

    +0

    @BillBell申し訳ありませんが、私はそれを私がそこに残していることに気づいていませんでした。コレクションページから製品リンクを拝借しているので、リンクは/ collections/collection-name/products/product-nameという形式になります。私はそれを使って私が望ましくないリンクを得ていないことを確認しました。私は今混乱を避けるためにそれを削除しました。 – barnesc

    答えて

    0

    あなたの問題はresponseSetに変換、REPONSEで重複を持っていることについて、主なので。これにより、すべてのデータの単一インスタンスが得られます。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_first()コマンドを使用することですされると仮定最初に一致した要素のみを抽出します。これは、IndexErrorを避け、選択に一致する要素が見つからない場合はNoneを返します。

    前:だから

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

    、それはする必要があります:あなたは 'コレクション' と '製品' を言及するが、実施例は、単に 'product_1' または 'product_2' を持っているか、あなたのxpathで

    >>> response.xpath('//div//a[contains(@href, "product")]/@href').extract_first() 
    u'/product_1' 
    
    +0

    を使用して私の問題を解決しました。しかし、私のスクリプトでは、すべての製品のリストを取得し、個々の製品ページのデータを取得する機能を使用して繰り返します。セットが順序付けされていないので、私は私の製品リンクを反復するときに、特定の順序でデータを取得しますが、Excelを使用してデータを並べ替えるだけでいいので、 – barnesc

    +0

    @barnesc、はい、セットを使用すると問題が発生します。これを軽減するには、 'OrderedSet'を使用してください。 –

    関連する問題