はじめに
この記事は「ニュース記事を棒読みに読ませるプログラムができるまで・・・」の続編になっております。まだ閲覧していない方は最初から見ていただけると幸いです。
今回はスクレイピングと正規表現を用いてタイトルと記事を切り抜いていきます。
Google Newsで記事を抜き出そうと考えたのですが、他のページに飛ぶと会員登録をしなければならないサイトが多かったためこの記事まではGoogle Newsを使用して、次回からは、記事が全部見れるサイトを使おうと考えています。
目次
正規表現とは
正規表現はパターンのある複数の文字列を一つの文字列で表現する方法です。
appleと書くのとAPPLEと書くのでは大文字と小文で書き方が違います。しかし、正規表現を用いると、'apple|APPLE'と書くだけで大文字と小文字で書かれていても対応できます。今回はタイトルや記事の文章を抜き出すために使います。sampleは以下の通りです。
class sample():
def regex(self):
#findallは検索したい文字や数字を含んだ文字や数字をすべて検索
text = r'I have a pen'
print('######### findall ##########')
print(re.findall('a' , text))
#searchは検索したい文字や数字が先頭からマッチしている文字や数字を検索
print('######### search ##########')
print(re.search('I',text))
print(re.search('ave',text))
#matchは検索した文字や数字が含んだ文字や数字を検索
print('######### match ##########')
print(re.match('I', text))
print(re.match('ave',text))
if __name__ == "__main__":
a = sample()
b = input('choise sanple(scraping, regex)')
print(b)
if b == 'regex':
a.regex()
今回主に使うのはfindallです。findallでタイトルやリンクを抜き出していきます。
タイトルを抜き出す
正規表現を用いてタイトルを抜き出します。正規表現は文字列から一部分を検索することも可能であり、この方法で抜き出しました。以下はGoogle Newsからタイトルを抜き出すsampleです。
#モジュールをインポート
import re
from urllib import request
from requests_html import HTMLSession
#インスタンス化
session = HTMLSession()
#クラス
class Parser():
#タイトル部分を抜き出している
def div_parser(self,p):
result = re.findall(r'class="WwrzSb(.*?)</a>',p)
print(result)
return result
#タイトルを抜き出し
def aria_label(self, p):
result = re.findall('aria-label="(.*?)"',p)
result = ''.join(result)
print(result)
return result
if __name__ == "__main__":
#インスタンス化
parser = Parser()
#URL
url = 'https://news.google.com/'
#地域設定(下は日本に設定されている)
params = {'hl':'ja', 'gl':'JP', 'ceid':'JP:ja'}
#URLを読み込む
r = session.get(url,params=params)
#HTMLから文字列に変換
r = r.text
#タイトルが書かれているclassを抜き出す
a = parser.div_parser(r)
#タイトルをaのリストから抜き出す
for i in a:
c = parser.aria_label(i)
GitHubに公開しているのでクローンして使ってみてください。
正規表現を使うにはimport re
と書きます。実際正規表現は、Request_HTMLでも使用できますが、今回は勉強するためということで使いました。
以下はsampleの一部分を抜き出したコードです。
def aria_label(self, p):
result = re.findall('aria-label="(.*?)"',p)
result = ''.join(result)
print(result)
return result
このコードの解説をしていきます。
result = re.findall('aria-label="(.*?)"',p)
re.findall
ではaria-label="(なんでもいい)"部分を探してくれて探した文字列をリストでまとめてくれる様になっています。pは検索対象が含まれている文字列です。
''.joint(result)
は空白部分を消して一文にしています。
(.*?)
は正規表現についてHTMLなどを正規表現で検索する場合によく使われます。.
は任意の文字を一つ、*
は0回以上の繰り返しで.*
でより多くの検索をすることが可能です(例<タイトル><はじめに><目次>を一気に検索することが可能)。`?`は0回か1回の繰り返しで`.*`より小さく検索することが可能です。(例<タイトル><はじめ><目次>の<タイトル>部分だけを検索することが可能)
まとめ
正規表現は様々な使い方が出来ますが、今回はmatch, search, findall
の3つを使って対象の文字列を表示しました。最初は、検索方法がイマイチわからないと思いますが、何回も使っていくうちに理解度が増していくと思うので、どんどん書いていきましょう。
最後に
今回は、正規表現を用いて、タイトルだけを表示するプログラムを作成しました。さきほど言いましたが、正規表現を使わなくてもRequest_HTML内に今回正規表現で用いた検索機能が入っているため、正規表現自体はいらないです。しかし、この記事の目的は、私がpythonのプログラムを学ぶためなので、あえて使いました。
次回は、ずんだもんの音声を用いてプログラム内でずんだもんを喋らせていきましょう。