では前回練習したウェブスクレイピングの続きを説明します。
前回の記事はこちらからどうぞ。
今日はヤフオクに表示されている入札価格と商品名などをスクレイピングしていきたいと思います。
requestsのライブラリをインストール
ではPythonから実際のウェブサイトにアクセスするにあたりHTTPリクエストを送ることになります。その際にRequestsのライブラリを使うのでインストールしましょう。
前回、virtualenvで環境を作った人はアクティベートすることを忘れずに!
pip install requests #最後のsを忘れずに!リクエスツです。
ではページのHTMLをスクレイピングします。
import requests #URLに対象となるURLを入力 html_text = requests.get('https://auctions.yahoo.co.jp/category/list/26318/?p=%E8%87%AA%E5%8B%95%E8%BB%8A%E3%80%81%E3%82%AA%E3%83%BC%E3%83%88%E3%83%90%E3%82%A4&auccat=26318&fixed=2&exflg=1&b=1&n=50&s1=featured&o1=d&nockie=1').text print(html_text)

ウェブページの内容が出てきました。
リスティングのHTMLを見る
ではデベロッパーツールで各リストを囲っているカードのエレメントをみます。


見てわかるようにliエレメントでProductというクラスがありますね。
ではこのProductクラスをすべてスクレイピングします。
from bs4 import BeautifulSoup import requests #URLに対象となるURLを入力 html_text = requests.get('https://auctions.yahoo.co.jp/category/list/26318/?p=%E8%87%AA%E5%8B%95%E8%BB%8A%E3%80%81%E3%82%AA%E3%83%BC%E3%83%88%E3%83%90%E3%82%A4&auccat=26318&fixed=2&exflg=1&b=1&n=50&s1=featured&o1=d&nockie=1').text soup = BeautifulSoup(html_text, 'lxml') listings = soup.find_all('li', class_='Product') print(listings)
Pythonファイルを実行してちゃんとスクレイピングできているか確かめましょう。
次に一つのリスティングから必要な情報を吸い取ります。
from bs4 import BeautifulSoup import requests #URLに対象となるURLを入力 html_text = requests.get('https://auctions.yahoo.co.jp/category/list/26318/?p=%E8%87%AA%E5%8B%95%E8%BB%8A%E3%80%81%E3%82%AA%E3%83%BC%E3%83%88%E3%83%90%E3%82%A4&auccat=26318&fixed=2&exflg=1&b=1&n=50&s1=featured&o1=d&nockie=1').text soup = BeautifulSoup(html_text, 'lxml') listing = soup.find('li', class_='Product') listing_title = listing.find('a', class_='Product__titleLink').text listing_price = listing.find('span', class_='Product__priceValue').text time_left = listing.find('span', class_='Product__time').text print(listing_title) print(listing_price) print(time_left)
ではこのリスティングをループさせます。
from bs4 import BeautifulSoup import requests #URLに対象となるURLを入力 html_text = requests.get('https://auctions.yahoo.co.jp/category/list/26318/?p=%E8%87%AA%E5%8B%95%E8%BB%8A%E3%80%81%E3%82%AA%E3%83%BC%E3%83%88%E3%83%90%E3%82%A4&auccat=26318&fixed=2&exflg=1&b=1&n=50&s1=featured&o1=d&nockie=1').text soup = BeautifulSoup(html_text, 'lxml') listings = soup.find_all('li', class_='Product') for listing in listings: listing_title = listing.find('a', class_='Product__titleLink').text listing_price = listing.find('span', class_='Product__priceValue').text time_left = listing.find('span', class_='Product__time').text print(listing_title) print(listing_price) print(time_left) print('---------')
10分ごとにスクレイピングを実行させる
では先ほどのコードをファンクションにして10分ごとに実行させるように設定します。
from bs4 import BeautifulSoup import requests import time #URLに対象となるURLを入力 html_text = requests.get('https://auctions.yahoo.co.jp/category/list/26318/?p=%E8%87%AA%E5%8B%95%E8%BB%8A%E3%80%81%E3%82%AA%E3%83%BC%E3%83%88%E3%83%90%E3%82%A4&auccat=26318&fixed=2&exflg=1&b=1&n=50&s1=featured&o1=d&nockie=1').text soup = BeautifulSoup(html_text, 'lxml') listings = soup.find_all('li', class_='Product') def find_listings(): for listing in listings: listing_title = listing.find('a', class_='Product__titleLink').text listing_price = listing.find('span', class_='Product__priceValue').text time_left = listing.find('span', class_='Product__time').text print(listing_title) print(listing_price) print(time_left) print('---------') if __name__ == '__main__': while True: find_listings() # minutes to wait time_wait = 10 print(f'Waiting {time_wait} minute(s)' ) time.sleep(time_wait * 60)
データをSCVに書き出す
日本語のエンコードは私は”utf_8_sig”で行いました。(アメリカのPCなので。。。
色々試してください。
from bs4 import BeautifulSoup import requests from csv import writer #URLに対象となるURLを入力 url = 'https://auctions.yahoo.co.jp/category/list/26318/?p=%E8%87%AA%E5%8B%95%E8%BB%8A%E3%80%81%E3%82%AA%E3%83%BC%E3%83%88%E3%83%90%E3%82%A4&auccat=26318&fixed=2&exflg=1&b=1&n=50&s1=featured&o1=d&nockie=1' html_text = requests.get(url).text soup = BeautifulSoup(html_text, 'lxml') listings = soup.find_all('li', class_='Product') with open('listings.csv', 'w', encoding='utf_8_sig', newline='') as f: thewriter = writer(f) header = ['Title', 'Price', 'Time Left'] thewriter.writerow(header) for listing in listings: listing_title = listing.find('a', class_='Product__titleLink').text listing_price = listing.find('span', class_='Product__priceValue').text time_left = listing.find('span', class_='Product__time').text info = [listing_title, listing_price, time_left] thewriter.writerow(info)