Pythonクローリング&スクレイピング[増補改訂版] ―データ収集・解析のための実践開発ガイドー その7
第3章 ライブラリによる高度なクローロング・スクレイピング
今回で3章は終わりです。電子書籍の
MongoDB に保存
スクレイピングしたものを MongoDB に保存します。
import lxml.html import requests from pymongo import MongoClient client = MongoClient('localhost', 27017) db = client.scraping collection = db.books collection.delete_many({}) tmp = requests.get("https://gihyo.jp/dp") html = lxml.html.fromstring(tmp.text) # href 要素の URL を絶対 URL にする html.make_links_absolute('https://gihyo.jp/') for a in html.cssselect('#listBook > li > a[itemprop="url"]'): url = a.get('href') p = a.cssselect('p[itemprop="name"]')[0] title = p.text_content() collection.insert_one({'url': url, 'title': title}) for link in collection.find().sort('_id'): print(link['_id'], link['url'], link['title'])
電子書籍の情報を MongoDB に保存する
from typing import Iterator import requests import lxml.html import time import re from pymongo import MongoClient def main(): """ クローラーのメイン処理 """ # MongoDB に保存する client = MongoClient('localhost', 27017) collection = client.scraping.ebooks # scrapingデータベースからebooksを得る # データを一意に識別するキーを格納するkeyフィールドにユニークなインデックスを作成する collection.create_index('key', unique=True) session = requests.Session() # 複数ページのクロールで負荷を軽減できる response = session.get('https://gihyo.jp/dp') urls = scrape_list_page(response) for url in urls: key_book = extract_key(url) ebook = collection.find_one({'key': key_book}) if not ebook: # データが存在しない場合、詳細ページにアクセスしてデータを取得する time.sleep(0.5) # 0.5秒ごとにアクセスする response_detail = session.get(url) ebook = scrape_detail_page(response_detail) collection.insert_one(ebook) for key, value in ebook.items(): print(key, value) def scrape_list_page(response: requests.Response) -> Iterator[str]: """ Response から URL を抜き出す """ html = lxml.html.fromstring(response.text) html.make_links_absolute(response.url) for a in html.cssselect('#listBook > li > a[itemprop="url"]'): url = a.get('href') yield url def scrape_detail_page(response: requests.Response) -> dict: """ 詳細ページのRequestから電子書籍の情報を取得する """ html = lxml.html.fromstring(response.text) ebook = { 'url': response.url, 'key': extract_key(response.url), 'title': html.cssselect('#bookTitle')[0].text_content(), 'price': html.cssselect('.buy')[0].text.strip(), # 空白を取り除く # リスト内包表記 'content': [normalize_spaces(h3.text_content()) for h3 in html.cssselect('#content > h3')], } return ebook def normalize_spaces(s: str) -> str: """ 連続する空白を一つの空白に置き換え、前後の空白を削除して新しい文字列を取得する """ # raw文字列として扱う return re.sub(r'\s+', ' ', s).strip() def extract_key(url: str) -> str: """ URL からキーを抜き出す (ISBN) """ match = re.search(r'/([^/]+)$', url) return match.group(1) if __name__ == '__main__': main()
本
Pythonクローリング&スクレイピング[増補改訂版] -データ収集・解析のための実践開発ガイド
- 作者: 加藤耕太
- 出版社/メーカー: 技術評論社
- 発売日: 2019/08/10
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る
感想
HTML ファイルをスクレイピングして、ハイパーリンクをたどることで電子書籍の情報を取得し、MongoDB に保存するというクローラーを作成しました。
スクレイピングしたデータを何に使うかも同時に考えていきたいですね。