ピックアップコラム
-
Pickup!
サイドバーとは?サイドバーを設置するメリットと書き方
-
Pickup!
カラー別にみてみる!WEBサイトにおける配色パターン
-
Pickup!
プラグインなし!オリジナルSNSシェアボタンの作り方ガイド
-
Pickup!
ワードプレスのプラグインで画像の圧縮・最適化をしてみた
今回は内部対策で必要な基本的なタグ(項目)について実際にスクレイピング処理をpythonを使って構築しつつ、作成してみたいと思います。
弊社ではSEO内部調査において項目を抽出する部分をシステム化していますが、複数サイトを保有していたりすると手動で抽出するのは大変かと思います。そこで簡単に抽出するプログラムを作成方法を含め紹介したいと思います。
ご存知の方もいらっしゃるとは思いますが、SEOの内部対策でよくチェックする基本的な項目についておさらいします。
上記1〜7の項目はSEO内部対策をする上でほぼ確実にチェックされると思います。
(この他にもwwwありなしの統一やSSL化、index数などチェック項目はあると思いますが、
今回は上記の7項目のみに絞って書いて見たいと思います)
seoの内部対策について詳しい項目や解説については以下のリンクを参照するとわかりやすいかもしれません。
プログラムを作成する前に、環境と前準備についてですが、今回、環境は以下のものを使用しております。
【OS】
・macOS X
【使用言語】
・python 3.6.1(3系)
【使用ライブラリ】
・openpyxl(エクセル操作に使用します)
・BeautifulSoup4(こちらを使用してスクレイピングします)
【使用ファイル】
urlList.txt(スクレイピング対象のURLを記載しておきます)
項目.xlsx(最終的にこのエクセルファイルを元に情報を出力します)
用意したurlList.txtにスクレイピング対象のURLを記載しておきます。
(下記、画像参照)
【urlList.txt】
【項目.xlsx】
今回、pythonを使った理由としては”なんか最近流行っているらしい・・”,
“beautifulsoupという便利なスクレイピング用ライブラリがあるらしい”
といった漠然とした理由です・・。
という訳で、次の章にてテキストファイルに記載されているURLの
スクレイピングをする処理について書いていきます。
まず初めに対象サイトのHTMLを丸ごとスクレイピングする処理を作成します。
当記事のサンプルでは2URL分です。(前述してある”urlList.txt”のURLを増やせばその分出力されます)
【scraping.py】
###モジュールのインポート### import urllib.request import requests from bs4 import BeautifulSoup ###モジュールのインポート### def scraping(url, j): #HTML取得(beutifulsoupを使用) r = requests.get(url) soup = BeautifulSoup(r.content, "html.parser") #文字列からタブと半角空白と全角空白と改行を削除 strhtml = soup.text strhtml = strhtml.replace(" ", "") strhtml = strhtml.replace("\n", "") strhtml = strhtml.replace("\r", "") #テキストファイルを書き込みで作成 f = open(str(j) + '_sample.txt', 'w') #取得したHTMLをファイルに書き込む f.write(strhtml) #ファイルを閉じる f.close() if __name__ == '__main__': #urlList.txtファイル読み込み lists = [] conf = '' for line in open('urlList.txt', 'r'): line = line.rstrip() lists = lists + [line] #テキストファイル名の先頭に数値をつける j = 1 #urlList.txt内のURL数だけループする for url in lists: #関数呼び出し scraping(url, j) #インクリメント j+=1
では、実際に実行してみます。
ターミナルにて”python scraping.py”を実行します。
(windowsの場合は、cmdにて実行)
出力した結果を確認します。
【1_sample.txt】
【2_sample.txt】
無事に、HTMLタグ内の文字列が取得できています!
次はこのHTMLから初めに述べた内部調査に必要な項目のみを
抽出していきたいと思います。
丸ごと抜き出したHTMLソースから上記で書いた基本的なチェック項目のみを抽出して
出力してみたいと思います。
上記の【scraping.py】の処理を修正、追加してみます。
今度は、テキストファイルだとわかりにくいので
あらかじめ作成したエクセルファイル(【項目.xlsx】)に
取得した情報を記載するようにします。
【scraping.py】
###モジュールのインポート### import urllib.request import requests import openpyxl as px from bs4 import BeautifulSoup from urllib.parse import urlparse from openpyxl.styles import Font, Color, colors ###モジュールのインポート### def scraping(Sheet1, url, j): #HTML取得(beutifulsoupを使用) r = requests.get(url) soup = BeautifulSoup(r.content, "html.parser") #header部分だけを抽出 header = soup.find("head") #タイトル title = header.find("title").text #ディスクリプション description = header.find("meta", attrs={"name": "description"}) #キーワード keywords = header.find("meta", attrs={"name": "keywords"}) #canonical can = header.find("link", rel="canonical") #viewport(レスポンシブ) viewport = header.find("meta", attrs={"name": "viewport"}) #タグ内容出力 Sheet1.cell(row = 2, column = j).value = url if title: Sheet1.cell(row = 3, column = j).value = title if can: Sheet1.cell(row = 6, column = j).value = can['href'] else: Sheet1.cell(row = 6, column = j).value = "設定なし" Sheet1.cell(row = 6, column = j).font = Font(color=colors.RED) if description: Sheet1.cell(row = 4, column = j).value = description['content'] else: Sheet1.cell(row = 4, column = j).value = "設定なし" Sheet1.cell(row = 4, column = j).font = Font(color=colors.RED) if keywords: Sheet1.cell(row = 5, column = j).value = keywords['content'] else: Sheet1.cell(row = 5, column = j).value = "設定なし" Sheet1.cell(row = 5, column = j).font = Font(color=colors.RED) if viewport: Sheet1.cell(row = 8, column = j).value = str(viewport) else: Sheet1.cell(row = 8, column = j).value = "設定なし" Sheet1.cell(row = 8, column = j).font = Font(color=colors.RED) #body部分だけを抽出 body = soup.find("body") com_h1tag = "" #h1タグを全て取得します h1tags = body.findAll("h1") #タグ内容出力(タグをまるごと) for h1tag in h1tags: if h1tag is not None: com_h1tag += str(h1tag) + "\n" Sheet1.cell(row = 7, column = j).value = com_h1tag #robots.txtの内容を取得します(トップページ下にある場合のみ) #ドメインを取得 parsed_url = urlparse(url) scheme = parsed_url.scheme domain = parsed_url.netloc re_url = scheme + "://" + domain + "/robots.txt" r2 = requests.get(re_url) soup2 = BeautifulSoup(r2.content, 'html.parser') if soup2: if r2.status_code == 200: Sheet1.cell(row = 9, column = j).value = soup2.text else: Sheet1.cell(row = 9, column = j).value = "robots.txtがトップページ下に存在しません。" Sheet1.cell(row = 9, column = j).font = Font(color=colors.RED) if __name__ == '__main__': #urlList.txtファイル読み込み lists = [] conf = '' for line in open('urlList.txt', 'r'): line = line.rstrip() lists = lists + [line] #excelテンプレート book = px.load_workbook('項目.xlsx') #excel結果ファイル名 bookname = '結果.xlsx' #excelシート Sheet1 = book.get_sheet_by_name('Sheet1') j = 2 #urlList.txt内のURL数だけループする for url in lists: #関数呼び出し scraping(Sheet1, url, j) #インクリメント j+=1 #excel保存 book.save(bookname)
結果のエクセルファイルを確認してみます。
【結果.xlsx】
無事、各項目が取得できているようです!
最後に今まで書いた処理と検索キーワードを絡めて
タイトルタグとh1タグにおけるキーワードの出現回数を
を自動で出力するようにしてみます。
【scraping.py】を以下のように修正します。
【scraping.py】
###モジュールのインポート### import sys import re import urllib.request import requests import openpyxl as px from bs4 import BeautifulSoup from urllib.parse import urlparse from openpyxl.styles import Font, Color, colors ###モジュールのインポート### def scraping(Sheet1, keyword, url, j): #HTML取得(beutifulsoupを使用) r = requests.get(url) soup = BeautifulSoup(r.content, "html.parser") #header部分だけを抽出 header = soup.find("head") #タイトル title = header.find("title").text #ディスクリプション description = header.find("meta", attrs={"name": "description"}) #キーワード keywords = header.find("meta", attrs={"name": "keywords"}) #canonical can = header.find("link", rel="canonical") #viewport(レスポンシブ) viewport = header.find("meta", attrs={"name": "viewport"}) #タグ内容出力 Sheet1.cell(row = 2, column = j).value = url if title: Sheet1.cell(row = 3, column = j).value = title if can: Sheet1.cell(row = 6, column = j).value = can['href'] else: Sheet1.cell(row = 6, column = j).value = "設定なし" Sheet1.cell(row = 6, column = j).font = Font(color=colors.RED) if description: Sheet1.cell(row = 4, column = j).value = description['content'] else: Sheet1.cell(row = 4, column = j).value = "設定なし" Sheet1.cell(row = 4, column = j).font = Font(color=colors.RED) if keywords: Sheet1.cell(row = 5, column = j).value = keywords['content'] else: Sheet1.cell(row = 5, column = j).value = "設定なし" Sheet1.cell(row = 5, column = j).font = Font(color=colors.RED) if viewport: Sheet1.cell(row = 8, column = j).value = str(viewport) else: Sheet1.cell(row = 8, column = j).value = "設定なし" Sheet1.cell(row = 8, column = j).font = Font(color=colors.RED) #body部分だけを抽出 body = soup.find("body") com_h1tag = "" #h1タグを全て取得します h1tags = body.findAll("h1") #タグ内容出力(タグをまるごと) for h1tag in h1tags: if h1tag is not None: com_h1tag += str(h1tag) + "\n" Sheet1.cell(row = 7, column = j).value = com_h1tag #robots.txtの内容を取得します(トップページ下にある場合のみ) #ドメインを取得 parsed_url = urlparse(url) scheme = parsed_url.scheme domain = parsed_url.netloc #urlリクエスト re_url = scheme + "://" + domain + "/robots.txt" r2 = requests.get(re_url) #リクエストページのHTMLをスクレイピング soup2 = BeautifulSoup(r2.content, 'html.parser') #リクエストが成功&HTMLが取得できた場合 if soup2: if r2.status_code == 200: Sheet1.cell(row = 9, column = j).value = soup2.text #リクエストが失敗した場合 else: Sheet1.cell(row = 9, column = j).value = "robots.txtがトップページ下に存在しません。" Sheet1.cell(row = 9, column = j).font = Font(color=colors.RED) #キーワード出現数 #結果格納用の変数 output1 = "" output2 = "" output3 = "" #htmlソースからscriptとstyleタグを除く for script in soup("script"): script.decompose() for style in soup("style"): style.decompose() strhtml = soup.text #文字列からタブと半角空白と全角空白と改行を削除 strhtml = strhtml.replace(" ", "") strhtml = strhtml.replace("\n", "") strhtml = strhtml.replace("\r", "") #キーワードが複数の場合(SEO 東京など)キーワード一つづつ配列へ kensakukeys = re.split(" +", keyword) #キーワードの数だけループ for kensakukey in kensakukeys: #ページ全体のキーワード出現数 cnt = strhtml.count(kensakukey) #タイトルキーワード出現数 titleKeyCnt = title.count(kensakukey) #h1キーワード出現数 h1KeyCnt = com_h1tag.count(kensakukey) #全て変数に入れる output1 += kensakukey + " : " + str(cnt) + "\n" output2 += kensakukey + " : " + str(titleKeyCnt) + "\n" output3 += kensakukey + " : " + str(h1KeyCnt) + "\n" #excelへ出力 Sheet1.cell(row = 10, column = j).value = output1 Sheet1.cell(row = 11, column = j).value = output2 Sheet1.cell(row = 12, column = j).value = output3 if __name__ == '__main__': argvs = sys.argv keyword = argvs[1] #urlList.txtファイル読み込み lists = [] conf = '' for line in open('urlList.txt', 'r'): line = line.rstrip() lists = lists + [line] #excelテンプレート book = px.load_workbook('項目.xlsx') #excel結果ファイル名 bookname = '結果.xlsx' #excelシート Sheet1 = book.get_sheet_by_name('Sheet1') j = 2 #urlList.txt内のURL数だけループする for url in lists: #関数呼び出し scraping(Sheet1, keyword, url, j) #インクリメント j+=1 #excel保存 book.save(bookname)
ここで、実際に実行してみます。
ターミナルにて”python scraping.py “[キーワード]””
を実行します。
(今回のサンプルでは[キーワード]の部分を”SEO 東京”にしております。)
出力された結果のエクセルファイル(結果.xlsx)を確認します。
【結果.xlsx】
結果それぞれのキーワード出現回数が記載されているのを確認しました!
SEOにおいて内部対策を行うことはとても重要です。
しかし、チェックすべきWebサイトやページが沢山有る場合、
一つ一つ手動で見ていくのはとても手間で時間のかかる作業です。
Pythonのbeautifulsoupを使ってスクレイピングを行うと
必要な情報だけを選別して瞬時に取得してチェックすることができます。
今回はPythonを使用しましたがPHPやRubyを使っても同様な
ことを行うことが出来ます。
今回はHTMLソースからタグを取得しただけですが、
Pythonのseleniumを使い、ブラウザを操作して
セーフブラウジングの確認やドメイン年齢取得などの
処理もまとめて自動取得が可能です。
この記事が呼んでくださった方の作業短縮の助けになれば幸いです。
受付時間:平日10:00~19:00(土・日・祝日を除く)