読者です 読者をやめる 読者になる 読者になる

DISTRICT 37

なにか

ScrapyでRSSをスクレイピング

Python

RSSリーダがすでにあるのに、スクレイピングをするなんて、、、いや、余計なことは考えない!!

スパイダーを作ってアイテムに入れるまで

今回のお題としては、はてぶの人気エントリのRSSを取ってきてアイテムに入れるまで。パイプラインに関しては今回は扱わない。

はてなブックマーク - 人気エントリー

まずはプロジェクトの作成

scrapy startproect hatena_hotentry

続いてスパイダーの生成

cd hatena_hotentry
scrapy genspider HotentrySpider feeds.feedburner.com

ここまでは何の問題もなく終わる。

それからシェルを使ってxpathの確認

scrapy shell http://feeds.feedburner.com/hatena/b/hotentry

例によってソースを確認して(※データは記事作成時のもの)

~前略~
  <item rdf:about="http://anond.hatelabo.jp/20170118083140">
    <title>映画館でわざわざ観る必要がない問題</title>
    <link>http://anond.hatelabo.jp/20170118083140</link>
    <description>「この世界の片隅に」はわざわざ映画館で観る理由がない。映画館で観る人はとにかく褒めたいアーリーアダプターと話題に乗っかりたいブロガーさんだけである。 いずれYoutubeかAmazonビデオでなら観るだろう。そしてレビューに「素晴らしかった!」とか書くんだろう。 この手の話はここ10年映画が衰退している理由でもある。 BDの普及、レンタル屋、テレビの高精細大画面化。 キネマ旬報はこの流れとともにお...</description>
    <content:encoded><![CDATA[<blockquote cite="http://anond.hatelabo.jp/20170118083140" title="映画館でわざわざ観る必要がない問題"><cite><img src="http://cdn-ak.favicon.st-hatena.com/?url=http%3A%2F%2Fanond.hatelabo.jp%2F" alt="" /> <a href="http://anond.hatelabo.jp/20170118083140">映画館でわざわざ観る必要がない問題</a></cite><p>「この世界の片隅に」はわざわざ映画館で観る理由がない。映画館で観る人はとにかく褒めたいアーリーアダプターと話題に乗っかりたいブロガーさんだけである。 いずれYoutubeかAmazonビデオでなら観るだろう。そしてレビューに「素晴らしかった!」とか書くんだろう。 この手の話はここ10年映画が衰退している理由でもある。 BDの普及、レンタル屋、テレビの高精細大画面化。 キネマ旬報はこの流れとともにお...</p><p><a href="http://b.hatena.ne.jp/entry/http://anond.hatelabo.jp/20170118083140"><img src="http://b.hatena.ne.jp/entry/image/http://anond.hatelabo.jp/20170118083140" alt="はてなブックマーク - 映画館でわざわざ観る必要がない問題" title="はてなブックマーク - 映画館でわざわざ観る必要がない問題" border="0" style="border: none" /></a> <a href="http://b.hatena.ne.jp/append?http://anond.hatelabo.jp/20170118083140"><img src="http://b.hatena.ne.jp/images/append.gif" border="0" alt="はてなブックマークに追加" title="はてなブックマークに追加" /></a></p></blockquote><img src="http://feeds.feedburner.com/~r/hatena/b/hotentry/~4/8vfCvvBcSzw" height="1" width="1" alt=""/>]]></content:encoded>
    <dc:date>2017-01-18T08:57:56+09:00</dc:date>
    <dc:subject>エンタメ</dc:subject>
    <hatena:bookmarkcount>197</hatena:bookmarkcount>
  </item>
  <item rdf:about="https://note.mu/wakusei2nd/n/n562b7d525897">
    <title>なぜ日本が世界共通語「Emoji」を生み出したのか、そしてその影響とは/古川健介『TOKYO INTERNET』|PLANETS|note</title>
    <link>https://note.mu/wakusei2nd/n/n562b7d525897</link>
    <description>なぜ日本が世界共通語「Emoji」を生み出したのか、そしてその影響とは/古川健介『TOKYO INTERNET』 ★☆★☆★☆★☆★☆★☆★☆★☆★☆ こちらの記事は、1/19(木)24:00までの期間限定で全文無料でお読みいただけます! ★☆★☆★☆★☆★☆★☆★☆★☆★☆ Daily PLANETS では毎月第2水曜日に、古川健介さんの連載『TOKYO INTERNET』を配信しています。連載...</description>
    <content:encoded><![CDATA[<blockquote cite="https://note.mu/wakusei2nd/n/n562b7d525897" title="なぜ日本が世界共通語「Emoji」を生み出したのか、そしてその影響とは/古川健介『TOKYO INTERNET』|PLANETS|note"><cite><img src="http://cdn-ak.favicon.st-hatena.com/?url=http%3A%2F%2Fnote.mu%2F" alt="" /> <a href="https://note.mu/wakusei2nd/n/n562b7d525897">なぜ日本が世界共通語「Emoji」を生み出したのか、そしてその影響とは/古川健介『TOKYO INTERNET』|PLANETS|note</a></cite><p><a href="https://note.mu/wakusei2nd/n/n562b7d525897"><img src="http://cdn-ak.b.st-hatena.com/entryimage/316512078-1484693699.jpg" alt="なぜ日本が世界共通語「Emoji」を生み出したのか、そしてその影響とは/古川健介『TOKYO INTERNET』|PLANETS|note" title="なぜ日本が世界共通語「Emoji」を生み出したのか、そしてその影響とは/古川健介『TOKYO INTERNET』|PLANETS|note" class="entry-image" /></a></p><p>なぜ日本が世界共通語「Emoji」を生み出したのか、そしてその影響とは/古川健介『TOKYO INTERNET』 ★☆★☆★☆★☆★☆★☆★☆★☆★☆ こちらの記事は、1/19(木)24:00までの期間限定で全文無料でお読みいただけます! ★☆★☆★☆★☆★☆★☆★☆★☆★☆ Daily PLANETS では毎月第2水曜日に、古川健介さんの連載『TOKYO INTERNET』を配信しています。連載...</p><p><a href="http://b.hatena.ne.jp/entry/https://note.mu/wakusei2nd/n/n562b7d525897"><img src="http://b.hatena.ne.jp/entry/image/https://note.mu/wakusei2nd/n/n562b7d525897" alt="はてなブックマーク - なぜ日本が世界共通語「Emoji」を生み出したのか、そしてその影響とは/古川健介『TOKYO INTERNET』|PLANETS|note" title="はてなブックマーク - なぜ日本が世界共通語「Emoji」を生み出したのか、そしてその影響とは/古川健介『TOKYO INTERNET』|PLANETS|note" border="0" style="border: none" /></a> <a href="http://b.hatena.ne.jp/append?https://note.mu/wakusei2nd/n/n562b7d525897"><img src="http://b.hatena.ne.jp/images/append.gif" border="0" alt="はてなブックマークに追加" title="はてなブックマークに追加" /></a></p></blockquote><img src="http://feeds.feedburner.com/~r/hatena/b/hotentry/~4/Yrhv1rRQwes" height="1" width="1" alt=""/>]]></content:encoded>
    <dc:date>2017-01-18T07:51:51+09:00</dc:date>
    <dc:subject>テクノロジー</dc:subject>
    <hatena:bookmarkcount>287</hatena:bookmarkcount>
  </item>
~後略~

なるほどね、itemタグからのtitleタグなのねと以下のように入れたら何も出なかった

In [1]: response.xpath('//item/title/text()').extract()
Out[1]: []

公式のドキュメントにそれっぽい記述があった。

Selectors — Scrapy 1.3.0 documentation

Once in the shell we can try selecting all <link> objects and see that it doesn’t work (because the Atom XML namespace is obfuscating those nodes):

But once we call the Selector.remove_namespaces() method, all nodes can be accessed directly by their names:

どうやらscrapyする相手がxmlとかrssとかatom形式の場合だと名前空間が邪魔して、素直に読めないからひと手間必要ということが分かった。

ということで以下のようにする

In [2]: response.selector.remove_namespaces()
In [3]: response.xpath('//item/title/text()').extract()

Out[3]: ['映画館でわざわざ(略)

これでOK。rssなどをscrapeした場合はresponse.selector.remove_namespaces()しないとデータが見えない。

ついでに<dc:subject>とかなってるタグ。そのままでは取れないけど、dcとかの前部分を無視してコロン以降の後部分を使えばデータが取れる

In [4]: response.xpath('//item/subject/text()').extract()

Out[4]: ['エンタメ(略)

shellで検証した結果を受けて編集したSpiderとItem

  • Spider
  • Item

最後にcrawlが動かせれば出来上がり

scrapy crawl Hotentry

(結果略)

scrapyを作る際はshellの検証が必須ですねぇ

関連記事

dragstar.hatenablog.com

dragstar.hatenablog.com