山傘のプログラミング勉強日記

プログラミングに関する日記とどうでもよい雑記からなるブログです。

Pythonクローリング&スクレイピング[増補改訂版] ―データ収集・解析のための実践開発ガイドー その4

第3章 ライブラリによる高度なクローロング・スクレイピング

Beautiful Soup

スクレイピング用のライブラリを持つ Beautiful Soup を使ってスクレイピングを行います。

from urllib.parse import urljoin
from bs4 import BeautifulSoup
import requests

url = 'http://gihyo.jp/dp'
req = requests.get(url)
soup = BeautifulSoup(req.text, 'html.parser')

for a in soup.select('#listBook > li > a[itemprop="url"]'):
  url = urljoin('http://gihyo.jp/dp', a.get('href'))
  p = a.select('p[itemprop="name"]')[0]
  title = p.text
  print(url, title)

pyquery

jQuery と同じような使い方ができる pyquery を使ってスクレイピングを行います。

from pyquery import PyQuery as pq
import requests

url = 'http://gihyo.jp/dp'
req = requests.get(url)

# PyQuery オブジェクトを得る
d = pq(url)
d.make_links_absolute('http://gihyo.jp/dp')

for a in d('#listBook > li > a[itemprop="url"]'):
  url = d(a).attr('href')
  p = d(a).find('p[itemprop="name"]').eq(0)
  title = p.text()
  print(url, title)

PyQuery オブジェクトの text メソッドでは、br 要素などが改行文字に含まれることが問題となります。

RSSスクレイピング

lxml を使って RSS からスクレイピングをします。RSSXML で標準化されているので、HTML よりもスクレイピングがしやすいです。

wget http://gihyo.jp/feed/rss2 -O rss2.xml
import lxml.etree

tree = lxml.etree.parse('rss2.xml')
root = tree.getroot()

for item in root.xpath('channel/item'):
  title = item.xpath('title')[0].text
  url = item.xpath('link')[0].text
  print(url, title)

CSS セレクターではなく、XPath を使って要素を取り出します。