2018年9月15日土曜日

Pythonでヤフーニュースをスクレイピング

最近スクレイピングの勉強しているから、目標を立てて使ってみる。
スクレイピングとは、ウェブサイトから情報を抽出するコンピュータソフトウェア技術のこと。らしいです。Wikipediaによると。

というわけで、情報集めを自動化できるようになりたいなぁってことで、練習練習。

目標:yahooニュースから更新されている記事の本文を取得する。

今回使うのはseleniumですね。ブラウザを自動操作できるテストツールらしいです。

水銀中毒に効きそうないい名前ですね!

pip install seleniumでインストールして、動かすためのブラウザも用意します。

このページからchromedriver.exeをダウンロード、カレントディレクトリーに置いておきます。



まずは必要そうなライブラリーをimportして、googlechromeでヤフーニュースのゲームタグを開きました。

"https://news.yahoo.co.jp/hl?c=game"

URLを変えれば好きなページでスクレイピングできます。

さて、開いたページから欲しそうな情報をどんどん引き抜いていきす。
とりあえず、記事のタイトルとURLが欲しいかな?
欲しい要素を右クリックして、検証を選んで



これだって感じのhtmlの行を見つけたら右クリックして、CSSセレクタをゲット。
CSSセレクタは要素を選択するための条件式みたいなものっぽい。
GoogleChromeは、html読まなくても、見つけられるから便利便利。



URL
#main > div.epCategory > div > ul > li:nth-child(1) > a
タイトル
#main > div.epCategory > div > ul > li:nth-child(1) > a > div > div.listFeedWrapCont > dl > dt

こんな感じのCSSセレクタがゲットできました。

find_elements_by_css_selector()という関数で、htmlを手に入れられるのでこんな感じで。


これ、取り出す要素が一つでもリストで帰ってくるのか...
li:nth-child(1)の1って数字が記事の1番目を指している気がするので、ここを変えれば全部の記事のタイトルとURLが手に入れられる気がする。
なんか、参考書で似たようなことをやるときにnth-of-type(n)って表記していたから、数字の代わりにnを入れれば、全部の要素を取り出せそう。

いいかんじ
このURLにをgooglechromeで開いて、記事の本文を見つければよさそう。
さっきやったことを繰り返して。

手に入れたURLをdriver.get()でページを開く。
タイトルと本文をリストに追加して、ページの情報をゲットです。



やっとできた。


<おまけ>
・前回起動したときなかった記事だけ欲しい
・記事をデータベース化して保存しておきたい
・ボイスロイドに読ませたい
って感じでコーディング



import time
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.options import Options
import subprocess as sps
import csv

def getcsv(path):
    csvlist = []
    with open(path, 'r') as f:
        reader = list(csv.reader(f))
    return reader

def savecsv(path,csvlist):
    with open(path,'w') as f:
        i = 0
        for ls1 in csvlist:
            j = 0
            for ls2 in ls1:
                f.write(ls2)
                if j < len(ls1) - 1:
                    f.write(",")
                j += 1
            if i < len(csvlist) - 1:
                f.write("\n")   
            i += 1

driver = webdriver.Chrome('./chromedriver')
driver.get("https://news.yahoo.co.jp/hl?c=game")
url_list = []
log_list = getcsv("yahoo_log.csv")
end = False
for a in driver.find_elements_by_css_selector('#main > div.epCategory > div > ul > li:nth-child(n) > a'):
    url = a.get_attribute('href')
    for log_url in log_list:
        if str(log_url[0]) == str(url):
            end = True
            break
    if end:
        break
    url_list.append([url])
for url in url_list:
    driver.get(url[0])
    for title in driver.find_elements_by_css_selector('#ym_newsarticle > div.hd > h1'): #タイトル
        url.append(title.text)
    for text in driver.find_elements_by_css_selector('#ym_newsarticle > div.articleMain > div.paragraph > p'): #本文
        url.append(text.text)
    time.sleep(1)
driver.quit()
log_list = url_list + log_list
for ls in log_list:
    ls[1] = ls[1].replace("\n","").replace("\u3000","")
    ls[2] = ls[2].replace("\n","").replace("\u3000","")
savecsv("yahoo_log.csv",log_list)
if len(url_list) > 0:
    intro = "ことのはゲームニュースのお時間です。最初のニュースはこちらです。"
    cmd = 'seikasay.exe -cid ' + "2000" + ' -speed ' + "1.20" + ' -pitch ' + "0.80" + ' -intonation ' + "1.00" + ' \"' + intro + '\"'
    sps.call(cmd,shell = True)
    for content in url_list:
        time.sleep(3)
        cmd = 'seikasay.exe -cid ' + "2000" + ' -speed ' + "1.20" + ' -pitch ' + "0.80" + ' -intonation ' + "1.00" + ' \"' + content[1] + '\"'
        sps.call(cmd,shell = True)
        time.sleep(2)
        for txt in content[2].split('\n'):
            cmd = 'seikasay.exe -cid ' + "2000" + ' -speed ' + "1.20" + ' -pitch ' + "0.80" + ' -intonation ' + "1.00" + ' \"' + txt + '\"'
            sps.call(cmd,shell = True)
        if content[0] == url_list[-1][0]:
            break
        time.sleep(2)
        intro = "次のニュースです。"
        cmd = 'seikasay.exe -cid ' + "2000" + ' -speed ' + "1.20" + ' -pitch ' + "0.80" + ' -intonation ' + "1.00" + ' \"' + intro + '\"'
        sps.call(cmd,shell = True)
       
    intro = "ことのはゲームニュースを終わります。"
    cmd = 'seikasay.exe -cid ' + "2000" + ' -speed ' + "1.20" + ' -pitch ' + "0.80" + ' -intonation ' + "1.00" + ' \"' + intro + '\"'
    sps.call(cmd,shell = True)


できた
github使えるようになって、ソースコードはれるようになりたい...

0 件のコメント:

コメントを投稿