更新が滞ってましたが、いい加減に進めようと思いまして、本日更新。
企画はこちらをご覧ください。本日は実際に新聞社から社説をぬきだすところまで記載します。なお、webスクレイピングは各社のwebページに禁止されているか書いてありますので、ご自身でよくご確認ください。
今回記載するコードには具体的な社名は、入れ込んでおりません。利用する場合は各社のwebポリシーを確認し、ご自身で修正してください。
またwebスクレイピングのプログラミングにはDOM木やXpathの知識がある程度必要です。知らない方は、「Xpath 入門」などで調べてみてください。
とりあえずコードを載せてみる
from selenium import webdriver #seleniumをインポート
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome import service as fs
import time
chrome_service = fs.Service(executable_path='./chromedriver')
driver = webdriver.Chrome(service=chrome_service)#chromeドライバーを指定
driver.implicitly_wait(10)#待機時間10秒
if __name__ == '__main__':
driver.get('https://hoge-shinbun/syasetsu') #hoge新聞
article_list = driver.find_element(By.XPATH,"//*[@id='article']")
latest_url = article_list.find_element(By.XPATH, 'a')
latest_url.click()
time.sleep(3)
#driver.get(latest_url)
article_title = driver.find_element(By.XPATH,'//h1')
print(article_title.text)
article_body = driver.find_element(By.XPATH,'//*[@id="article-d"]')
articles = article_body.find_elements(By.XPATH, 'p')
for p_body in articles:
print(p_body.text)
こんな感じになりました。新聞社はhoge新聞となります。
コードの説明
seleniumを利用しています。webページからのデータ収集とそのデータの分析をこれ一つでできるためです。
web driverはGoogle chromeを利用しています。バージョンは103です。
動作について、まずimportで必要なライブラリを読み込みます。seleniumのドライバは前述のとおりchromeを設定します。
driver.getでhoge新聞の社説のwebページを読み込みます。特に指定していないので、これが実行されるとchromeが立ち上がります。
その後、driver.find_element(By.XPATH,"//*[@id='article']")で全体のページから読み込みたい個所を指定します。今回は社説に関する箇所を指定しています。
社説(読み込みたい場所)はどうやって調べるの?
そもそも読み込みたい場所はどう調べるのか。
まずは新聞社のwebに実際にアクセスしてください。そして読み込みたい場所に当たりをつけます(たとえばある日の社説のリンク)。
そしたらお使いのブラウザの解析ツールを開きます。開き方は各ツールで異なります。例えばchromeなら「Ctrl + Shift + c」で開けます。
ツールを開くと、今見ている新聞社のwebのHTMLなどを見ることができます。そこであたりをつけた場所のXPathを調べます。
Xpathが何かわからない方は、検索してみてください。簡単にいうとwebページ上の場所を示す、情報になります。これは木構造で作られています。
latest_url = article_list.find_element(By.XPATH, 'a')
で、読みたい場所の中の一番初めのaタグの記事を指定します。なぜ、一番初めかというと大体の社説が上から新しい日付順で並んでいるためです。
latest_url.click()
を実行すると、その最新の記事のwebをクリックしたことと同等の操作を得られます。ブラウザが立ち上がっていればそのページに遷移したことがわかるでしょう。そのあとのsleepはエラー回避用です。これを入れておかないとresponseエラーになることがありました。
そのあとは、article_title = driver.find_element(By.XPATH,'//h1')
でタイトル部分を取得しています。print部分は表示用です。
記事の本体は、article_body = driver.find_element(By.XPATH,'//*[@id="article-d"]')
でとってます。
次のarticles = article_body.find_elements(By.XPATH, 'p')
は記事の本体部分から記事の文書だけを取り出しています。find_elementsメソッドを利用すると、複数の要素をリストとして取得できます。これをやらないと余計な広告などが入ってきてしまいます。また、今回はpタグで抜き出すことにしていますが、pタグに格納されているかは新聞社によって異なります。実際に各社のページで確かめてください。
そのあとのfor文はarticlesから記事を一つ一つ抜き出す作業です。
注意点
このコード、これくらい短いですが、実行するのに2分くらいかかります。seleniumが遅いといわれる所以ですね。速さを求める場合は、requestライブラリとbeautiful soapライブラリを利用したほうが良いと思います。
また今回、ページ遷移でdriver.getをしようとして、エラーに当たりました(#でコメントアウトしているところ。正確にはlatest_urlをきちんとlatest_url.get_attribute("href")などで文字にしたがダメだった。)。初めに良く調べなかったのが悪いのですが、普通今回の記載しているようにページ遷移には .click のメソッドを利用しましょう。
あとがき
ものすごく単純なコードを書くのに、2時間弱を費やしてしまった。実は試行錯誤をいろいろしています。
特にコード自体の修正というより、必要な情報を抜き出すXpathをツールで調べることに時間を費やしていたと思います。今はブラウザのツールが発達しているので、結構お手軽に調べられるのですが、昔は自分でいろいろたどる必要があり、さらに膨大な時間を費やしていました。
Web系のプログラムを書く人はCSSもそうですがDOM木とXpathは必須教養ですので、何かに触れて解析ツールを開いてみることをお勧めします。右クリック禁止のページでも内容をコピーしたりできて便利です。
今回は管理人の趣味で新聞社の社説を題材にしましたが、xpathさえ理解できればどのようなwebページにも応用可能です。自動化の夢が広がりますね。
ではまた次回。