2017-04-17 43 views
0

Scrapyは本当に強力なツールですが、XPathに関しては時には苛立っています。
以下のhtmlから、<b>January 2017</b><b>February 2017</b>の間のリンクとリンクテキスト(Title 1Title 2など)を抽出し、それらを「パート」ごとにグループ化したいと思います。 実際のhtmlです。ScrapyとXPath - セクション間のリンクとリンクテキストの選択

<!DOCTYPE html> 
<html> 
    <head> 
     <meta charset="UTF-8"> 
     <title>Scrapy</title> 
    </head> 
    <body> 
     <hr size=1> 
     <h2 style="margin-top: 36px; margin-bottom: 24px"> 
     Abcd efgh for 2017 
     </h2> 
     Part 1 | 
     Part 2 | 
     Part 3 | 
     Part 4 | 
     <a href="#">A very bold title</a> 
     <hr size="1" style="margin-top: 36px; margin-bottom: 24px"> 
     <a name="part1"></a> 
     <h3>Part 1</h3> 
     <ul> 
     </ul> 
     <a name="part2"></a> 
     <h3>Part 2</h3> 
     <ul> 
     </ul> 
     <a name="part3"></a> 
     <h3>Part 3</h3> 
     <ul> 
     </ul> 
     <a name="part4"></a> 
     <h3>Part 4</h3> 
     <ul> 
     </ul> 
     <div style="margin-top: 36px; margin-bottom: 24px"> 
     <a name="non_rep"></a> 
     <h3>Abcd efgh</h3> 
     </div> 
     <b>January 2017</b> 
     <ul> 
     <li> 
      <b>Part1 1</b> 
     </li> 
     <ul> 
      <li> 
       <a href="/cgi-bin/o.pl?file=/a/1.htm">Title 1</a> 
      </li> 
      <br> 
      <li> 
       <a href="/cgi-bin/o.pl?file=/a/11.htm">Title 2</a> 
      </li> 
      <br> 
     </ul> 
     <li> 
      <b>Part1 2</b> 
     </li> 
     <ul> 
      <li> 
       <a href="/cgi-bin/o.pl?file=/a/2.htm">Title A</a> 
      </li> 
      <br> 
      <li> 
       <a href="/cgi-bin/o.pl?file=/a/22.htm">Title B</a> 
      </li> 
      <br> 
     </ul> 
     <li> 
      <b>Part1 3</b> 
     </li> 
     <ul> 
      <li> 
       <a href="/cgi-bin/o.pl?file=/a/3.htm">Some text 1</a> 
      </li> 
      <br> 
      <li> 
       <a href="/cgi-bin/o.pl?file=/a/33.htm">Some Text 2</a> 
      </li> 
     </ul> 
     </ul> 
     <b>February 2017</b> 
     <ul> 
     <li> 
      <b>Part1 1</b> 
     </li> 
     <ul> 
      <li> 
       <a href="/cgi-bin/o.pl?file=/b/1.htm">Title 1</a> 
      </li> 
      <br> 
      <li> 
       <a href="/cgi-bin/o.pl?file=/b/11.htm">Title 2</a> 
      </li> 
      <br> 
     </ul> 
     <li> 
      <b>Part1 2</b> 
     </li> 
     <ul> 
      <li> 
       <a href="/cgi-bin/o.pl?file=/b/2.htm">Title A</a> 
      </li> 
      <br> 
      <li> 
       <a href="/cgi-bin/o.pl?file=/b/22.htm">Title B</a> 
      </li> 
      <br> 
     </ul> 
     <li> 
      <b>Part1 3</b> 
     </li> 
     <ul> 
      <li> 
       <a href="/cgi-bin/o.pl?file=/b/3.htm">Some text 1</a> 
      </li> 
      <br> 
      <li> 
       <a href="/cgi-bin/o.pl?file=/b/33.htm">Some Text 2</a> 
      </li> 
     </ul> 
     </ul> 
     <b>March 2017</b> 
     <ul> 
     <li> 
      <b>Part1 1</b> 
     </li> 
     <ul> 
      <li> 
       <a href="/cgi-bin/o.pl?file=/c/1.htm">Title 1</a> 
      </li> 
      <br> 
      <li> 
       <a href="/cgi-bin/o.pl?file=/c/11.htm">Title 2</a> 
      </li> 
      <br> 
     </ul> 
     <li> 
      <b>Part1 2</b> 
     </li> 
     <ul> 
      <li> 
       <a href="/cgi-bin/o.pl?file=/c/2.htm">Title A</a> 
      </li> 
      <br> 
      <li> 
       <a href="/cgi-bin/o.pl?file=/c/22.htm">Title B</a> 
      </li> 
      <br> 
     </ul> 
     <li> 
      <b>Part1 3</b> 
     </li> 
     <ul> 
      <li> 
       <a href="/cgi-bin/o.pl?file=/c/3.htm">Some text 1</a> 
      </li> 
      <br> 
      <li> 
       <a href="/cgi-bin/o.pl?file=/c/33.htm">Some Text 2</a> 
      </li> 
     </ul> 
     </ul> 
     <b>April 2017</b> 
     ... 
     ... 
     So on so forth 
    </body> 
</html> 

結果は次のようになります。

January 2017 
Part1 1 
Title: Title 1, link: /cgi-bin/o.pl?file=/a/1.htm 
Title: Title 1, link: /cgi-bin/o.pl?file=/a/1.htm 
Part1 2 
Title: Title 1, link: /cgi-bin/o.pl?file=/a/2.htm 
Title: Title 1, link: /cgi-bin/o.pl?file=/a/22.htm 
Part1 3 
Title: Title 1, link: /cgi-bin/o.pl?file=/a/3.htm 
Title: Title 1, link: /cgi-bin/o.pl?file=/a/33.htm 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
February 2017 
Part1 1 
Title: Title 1, link: /cgi-bin/o.pl?file=/b/1.htm 
Title: Title 1, link: /cgi-bin/o.pl?file=/b/1.htm 
Part1 2 
Title: Title 1, link: /cgi-bin/o.pl?file=/b/2.htm 
Title: Title 1, link: /cgi-bin/o.pl?file=/b/22.htm 
Part1 3 
Title: Title 1, link: /cgi-bin/o.pl?file=/b/3.htm 
Title: Title 1, link: /cgi-bin/o.pl?file=/b/33.htm 

私は無駄に//text()[following-sibling::b/text()='January 2017']/following::a[contains(@href, 'cgi-bin')]/text()と同様の呪文を試してみました。

どのようにアプローチする必要がありますか?

答えて

1

ツリー構造が非常にフラットなので、設定全体がちょっと面倒です。しかし、それはこのパターンに従うことがわかります:ノードのテキストと<ul>の直下にデータがあります。
私たちはいくつかのループとfollowing-sibling::ul[1] xpathでほしいと思うすべてを見つけることができます。

それが原因で、トリプルループで少し醜いですが、あなたはそれが非常に簡単だと無視した場合:

# any <b> node that contains 201x (a year) 
nodes = response.xpath("//b[re:test(text(),'201\d')]") 
for node in nodes: 
    # get date node data 
    name = node.xpath('text()').extract_first() 
    parts = node.xpath('following-sibling::ul[1]//li/b') 
    for part in parts: 
     # the same with part node data 
     part_name = part.xpath('text()').extract_first() 
     links = part.xpath("../following-sibling::ul[1]//a") 
     for link in links: 
      # finally, we have date, part and link data! Put it together. 
      item = dict() 
      item['date_name'] = name 
      item['part_name'] = part_name 
      item['link_name'] = link.xpath('text()').extract_first() 
      item['link_url'] = link.xpath('@href').extract_first() 
      yield item 
関連する問題