Section 17 Craigslist Scraper
Craiglistのスパイダーを作る準備をする
$ source venv_0512/bin/activate $ cd venv_0512 $ scrapy startproject craiglist $ scrapy genspider jobs newyork.craigslist.org
最終的なコード
タイトルの取得方法
$ scrapy shell 'https://newyork.craigslist.org/search/aap' In [1]: response.status Out[1]: 200
検証で確認する。result-titleで検索すると120抽出される。
In [3]: response.xpath('//a[@class="result-title hdrlnk"]') Out[3]: [<Selector xpath='//a..... In [5]: len(response.xpath('//a[@class="result-title hdrlnk"]')) Out[5]: 120 In [6]: response.xpath('//a[@class="result-title hdrlnk"]').extract In [8]: response.xpath('//a[@class="result-title hdrlnk"]/text()').extract() Out[8]: ['🔴1BR-🔥BEAUTIFUL! BIG APARTMENT!🔥 BED-STUY!🔴spac', '2BD- 13 ft. Ceilings, Floor-to-Ceiling Windows, Water View!- Stamford', 'NO FEE, GREAT DEAL - 3 BEDROOM NEWLY RENOVATED, A, C TRAINS', 'The price is right, for this 4 Bedroom Gem!', '# Massive renovated studio by Brooklyn College/Triangle Junction#', 'beautiful one bedroom apartment for rent', 'BEDSTUY🔮BRAND NEW 3BR,2BA APT
この状態だと、ターミナルにプリントするだけ。
yield文を入れてitemを保存できるようにする。
タイトルのテキスト、日付け、URLの取得
検証でresult-rowを確認する。120個あることが確認できる。
日付け
In [17]: listings = response.xpath('//li[@class="result-row"]') In [18]: listings.xpath('.//*[@class="result-date"]/@datetime').extract_first() Out[18]: '2018-05-21 19:56'
タイトルのリンクとテキストの取得
In [20]: listings.xpath('.//a[@class="result-title hdrlnk"]/@href').extract_first() Out[20]: 'https://newyork.craigslist.org/brk/abo/d/1br-beautiful-big-apartment/6593403069.html' In [21]: listings.xpath('.//a[@class="result-title hdrlnk"]/text()').extract_first() Out[21]: '🔴1BR-🔥BEAUTIFUL! BIG APARTMENT!🔥 BED-STUY!🔴spac'
Nextの対処方法
検証で確認する。クラス、タイトル、aタグの3つで確認できる。
実際に取得できるか確認してみる。
In [23]: response.xpath('.//*[@class="button next"]/@href').extract_first() Out[23]: '/search/aap?s=120' In [24]: response.xpath('.//*[@title="next page"]/@href').extract_first() Out[24]: '/search/aap?s=120'
コードに設定する。
もし、nextpageなら、yieldする。
requestメソッドで次のページのurlを渡して、同じようにパースさせる。
urljoin を使うことで、相対URLから絶対URLを求めることができます。
In [26]: next_page_url Out[26]: '/search/aap?s=120' In [27]: response.urljoin(next_page_url) Out[27]: 'https://newyork.craigslist.org/search/aap?s=120'
各々のページの情報を取得する(img、タイトル、タグ、ディスクリプション)
タグの取得をする。
検証で確認する。
shellで確認する。クラス→bタグで絞る→テキストで絞る→extract_first()で絞る
In [33]: response.xpath('//*[@class="attrgroup"]/span[1]') Out[33]: [<Selector xpath='//*[@class="attrgroup"]/span[1]' data='<span class="shared-line-bubble"><b>1BR<'>, <Selector xpath='//*[@class="attrgroup"]/span[1]' data='<span>cats are OK - purrr</span>'>] In [34]: response.xpath('//*[@class="attrgroup"]/span[1]/b') Out[34]: [<Selector xpath='//*[@class="attrgroup"]/span[1]/b' data='<b>1BR</b>'>, <Selector xpath='//*[@class="attrgroup"]/span[1]/b' data='<b>0Ba</b>'>] In [38]: response.xpath('//*[@class="attrgroup"]/span[1]/b/text()').extract_first() Out[38]: '1BR'
写真の取得をする。
検証で確認する。
shellで確認する。
In [39]: response.xpath('//*[@id="thumbs"]//@src').extract() Out[39]: ['https://images.craigslist.org/00C0C_5xLZMGp1V0J_50x50c.jpg', 'https://images.craigslist.org/00T0T_e3wrbpV2sNx_50x50c.jpg', 'https://images.craigslist.org/00B0B_9c03032CV8w_50x50c.jpg', 'https://images.craigslist.org/00N0N_kJgrC0DEaEU_50x50c.jpg', 'https://images.craigslist.org/00G0G_hYwRcT4QvIh_50x50c.jpg', 'https://images.craigslist.org/00G0G_iUwqMdtxsYE_50x50c.jpg', 'https://images.craigslist.org/00u0u_aqZ1Du5NcgC_50x50c.jpg', 'https://images.craigslist.org/00o0o_hKqhzTYad9J_50x50c.jpg', 'https://images.craigslist.org/00f0f_bKlI23qfgJr_50x50c.jpg', 'https://images.craigslist.org/00A0A_jug343LsOTz_50x50c.jpg', 'https://images.craigslist.org/00v0v_6i1YfvZx0Iz_50x50c.jpg', 'https://images.craigslist.org/00x0x_ik1rXEWsg06_50x50c.jpg']
以下のコードでサイズを指定する。
images = [image.replace('50x50c', '600x450') for image in images]
Descriptionを取得する。
検証する。
コードを設定する。
response.xpath('//*[@id="postingbody"]/text()').extract()
最後に全てをyieldして終わる。