Python学習【365日チャレンジ!】338日目のマスターU(@Udemy11)です。
年が開けて2週間が経ちましたが、なかなか正月気分が抜けません。
コマーシャルで杏さんが唐揚げを食べながらおいしそうにビールを飲む映像を見ていると、無性にビールを飲みながら、山盛りのからあげを食べたくなり、もも肉を6枚買ってからあげを作りました。
市販されているから揚げ粉とゆずをまぶして自分で衣を付けた唐揚げを作ったのですが、圧倒的に市販されているから揚げ粉を使ったからあげのほうがジューシーでおいしかったので、これからは無理をせずに市販のから揚げ粉を使うことを決心しました。
当たり前ですが、さすがにいろいろと試された結果の商品だけはありますね。
それでは今日も、Python学習を始めましょう。
昨日の復習
昨日は、Google検索の1ページめにヒットしたページのURLを抽出しました。
Google検索で「Google検索の結果からURLを抽出する」と調べてヒットするページで紹介されているGoogle仕様と、現在のGoogleの仕様が変更されているようで、必要なタグのクラスがややこしくて、抽出するのにかなり時間がかかってしまいました。
Googleの仕様が変わったのか、div
要素のクラス名が変わってしまっていて、紹介されているコードでは抽出できませんでした。
HTMLコードを読み解くのにも時間がかかったし、余分なURLをどうするかを考えるのにもちょっと頭を使いました。
今日は、抽出したURLにアクセスして、省略されていない完全なタイトルを抽出します。
全体コード
今回のコードは、ヒットしたURLを抽出したときにアンカーの#
が含まれている場合は、#
が%23
に変換されて取得されるので、ヒットしたURLにアクセスできません。
他のエラーも起こっていたので、なにぶん穴だらけのコードだということをご理解ください。
こちらが全体のコードです。
import time
from bs4 import BeautifulSoup
import lxml.html as lx
import re
import requests
search_query = '鬼滅の刃 映画感想'
r = requests.get('https://www.google.co.jp/search?hl=jp&gl=JP&num=10&q=' + search_query)
html_l = r.text.encode()
root = lx.fromstring(html_l)
url_results = []
for t in root.cssselect('div.kCrYT a'):
u_res = re.sub(r'/url\?q=|&sa.*', '', t.get('href'))
u_result = re.sub(r'/search\?gl=JP&ie=UTF-8&q=.*', '', u_res)
if u_result != '':
url_results.append(u_result)
print(u_result)
title_results = []
for i in url_results:
t_html = requests.get(i)
t_soup = BeautifulSoup(t_html.text, 'lxml')
title = t_soup.find('title')
print(title.text)
time.sleep(2)
出力結果
ちなみに実際にGoogleでした画像がこちら
矢印のリンク先にアクセスして、省略されているタイトルもきちんと取得できています。
鬼滅の刃 映画感想
で検索するとうまく抽出できるのですが、Udemy
で検索するとどうもうまく抽出できませんでした。
ヒットしたURLの抜き出しがうまくいかなかったり、アクセス先が存在しなかったりしてエラーが起こってしまうようなので、この先tyr-except
などを使った例外処理のコードも加える必要があります。
とりあえず、パートに分けてコードを確認してみます。
インポートするライブラリ
import time
from bs4 import BeautifulSoup
import lxml.html as lx
import re
import requests
time
、BeautifulSoup
、lxml
、re
、requests
です。
time
は、抽出したURLへのアクセスが不正なアクセスにならないよう、時間を開けてアクセスするために使います。
BeautifulSoup
、lxml
は、取得した値の解析に使い、re
は正規表記、requests
はHTTPでデータを取得するために使います。
URLの取得
search_query = '鬼滅の刃 映画感想'
r = requests.get('https://www.google.co.jp/search?hl=jp&gl=JP&num=10&q=' + search_query)
html_l = r.text.encode()
root = lx.fromstring(html_l)
url_results = []
for t in root.cssselect('div.kCrYT a'):
u_res = re.sub(r'/url\?q=|&sa.*', '', t.get('href'))
u_result = re.sub(r'/search\?gl=JP&ie=UTF-8&q=.*', '', u_res)
if u_result != '':
url_results.append(u_result)
print(u_result)
こちらのコードは昨日のURLを抽出するコードと同じですが、変数をu_res
やu_result
に変更して、検索ワードを鬼滅の刃 映画感想
にしています。
タイトルの取得
for i in url_results:
t_html = requests.get(i)
t_soup = BeautifulSoup(t_html.text, 'lxml')
title = t_soup.find('title')
print(title.text)
time.sleep(2)
22行目からがURLにアクセスして、タイトルを取得するためのコードになります。
22行目でfor
ループで取得したurl_results
を回します。
23行目でリストにあるURLにアクセスして値を取得して、24行目のBeautifulSoup
でオブジェクトを作り、25行目でオブジェクトからtitle
タグを抜き出し、26行目でタイトルタグのテキスト部分だけを出力しています。
出力後は2秒まって、次のループに進んでいます。
まとめ
最初に書きましたが、このコードは例外には対応していないので、エラーが起こればきちんと値を取得することができません。
エラーが起こったときにもプログラムが最後まで処理ができるように、例外に対応できるコードにする必要があります。
また、今回のコードでは同じような処理をするBeautifulSoup
とlxml
を使っているので、どちらか一方に統一したほうがいいのかもしれません。
明日は、もう少しこのコードを見やすくわかりやすいコードに作り変えていきたいと思います。
それでは、明日もGood Python!