こんにちは、オイケです。
ブログを運営している人で、数十記事以上書くと、公開中記事の、
- 記事公開日
- 記事最終更新日
- 記事タイトル
- description内容
- htagタイトル
などの一覧が欲しくなりませんか?
または、競合サイト分析のために、上記一覧が欲しくなりませんか?
WordPressを使っている人であれば、「投稿一覧」で自分のブログの、
- 記事公開日
- 記事タイトル
の一覧を確認することができますが、
- 記事最終更新日
- description内容
- htagタイトル
については、各記事の編集画面に入らないと確認することができません。
しかし、パソコンにPythonのAnacondaをインストールして、この記事に添付しているPythonコードをダウンロードして実行することで、自分のブログやライバルサイトの記事タイトル一覧、description一覧、htag一覧を無料で簡単に作ることができます。
作成した一覧を見ることで、これまで作成したブログ記事の、
- 記事タイトル
- description内容
- htagタイトル
の改善すべき点に気付くことができます。
気付き次第、記事をリライトすることで、少しだけSEO評価が上がり、アクセスアップする可能性があります。
また、競合サイト分析においても、
- 記事タイトル
- description内容
- htagタイトル
を一覧で見ることで、競合サイトの、
- サイト構成
- 記事概要
- 狙っているキーワード
などを知ることができ、自分のブログの改善に繋げることができます。
私自身、Pythonのプログラミング経験はゼロでしたが、YouTubeの「キノコード / プログラミング学習チャンネル」さんの動画を見て、パソコンにPythonのAnacondaを無料でインストールして、試行錯誤しながら自分でPythonコードを書いて、自分のブログサイトの、
- 記事公開日
- 記事最終更新日
- 記事タイトル
- description内容
- htagタイトル
などの一覧を作成しました。
一覧を見た結果、いくつか気付きがあり、ブログ記事をリライトしました。
では、Pythonコードの実行環境構築、Pythoコードの実行方法、作成した一覧の内容について解説しますね。
Pythonコードの実行環境構築
Pythonコードの実行環境構築については、Youtubeの「キノコード / プログラミング学習チャンネル」さんの以下の動画に従って、無料で簡単に構築できます。
- 【Python超入門コース】01.コース紹介|初心者にわかりやすいようなコースを作りました【プログラミング初心者向け入門講座】 全14回
- Pandas入門|01.コース紹介|Excelやcsv操作、データ分析、グラフ化などができるPythonのライブラリの使い方を初心者向けに解説【プログラミング初心者向け】 全14回
極力時間をかけずに環境構築だけを行いたい人は、上記2だけを観ればOKです。
ブログサイトの記事タイトル一覧・description一覧・htag一覧を作成する方法
実行フローの全体
上図は、ブログサイトの記事タイトル一覧・description一覧・htag一覧を作成する実行フローの全体図です。
ライブラリのインストール
Pythonコード:00_library_install.ipynbを実行し、seleniumライブラリとbeautifulsoupライブラリをインストールします。
一度ライブラリをインストールすれば、パソコンをシャットダウンした後もインストール情報が残っているため、ライブラリの再インストールの必要はありません。
サイトマップリストの作成
まず、01_Sitemap.ipynb内の「https://xxxxxx/sitemap.xml」の部分を、自分のブログのsitemap.xmlのURLに合わせて変更します。
次に、Phthonコード:01_Sitemap.ipynbを実行すると、自分のブログのsitemap.xmlを読み取り、そこに記載されているサイトマップリストを、01_xml.csvに出力します。
記事のURLリスト作成
Pythonコード:02_article_list.ipynbを実行すると、01_xml.csvを読み取り、そこの記載されているブログ記事のURLリストを、02_url.csvに出力します。
記事タイトル一覧・description一覧の作成
Pythonコード:03_description.ipynbを実行すると、02_url.csvを読み取り、各ブログ記事内の、
- 記事公開日
- 記事最終更新日
- 記事タイトル
- description内容
の一覧を、03_description.csvに出力します。
記事タイトル一覧・htagタイトル一覧の作成
Pythonコード:04_htag.ipynbを実行すると、、02_url.csvを読み取り、各ブログ記事内の、
- 記事タイトル
- description内容
- htagタイトル
の一覧を、04_htag_list.csvに出力します。
ライブラリのインストール方法
上図は、JupyterLabでPythonコード:00_library_install.ipynbを開いた状態です。
一番上のセルにカーソルを移動し、「Shift+Enter」または赤丸で囲んだ三角印をクリックすることで、各セルのコードが実行され、seleniumuライブラリとbeautifulsoupライブラリがインストールされます。
サイトマップリストの作成方法
上図は、JupyterLabでPythonコード:01_Sitemap.ipynbを開いた状態です。
まず、グレーで塗りつぶした前後の””で囲んだ箇所を、自分のブログのサイトマップに変更します。
一番上のセルにカーソルを移動し、「Shift+Enter」することで、各セルのコードが実行され、自分のブログのsitemap.xmlを読み取り、そこに記載されているサイトマップリストを、01_xml.csvに出力します。
上図は、01_xml.csvの一例です。
私のブログの場合は、「sitemap-pt-post-年-月.xml」を参照することで、公開中記事一覧リストを作成することができます。
「sitemap-misc.xml」や「sitemap-tax-category.xml」も参照しても、公開中記事一覧リストを作成することはできますが、記事が重複し、この後の処理時間が長くなるため、不要行を削除し、01_xml.csvを上書き保存しました。
記事のURLリスト作成方法
上図は、JupyterLabでPythonコード:02_article_list.ipynbを開いた状態です。
一番上のセルにカーソルを移動し、「Shift+Enter」することで、各セルのコードが実行され、01_xml.csvを読み取り、各xmlを参照し、そこに記載されている記事のURLを、02_url.csvに出力します。
上図は、02_ur.csvの一例で、公開中記事のURL一覧です。
02_ur.csvには、固定記事のURLも含まれます。固定記事をこの後の調査対象外にしたい場合は、該当行を削除し、上書き保存します。
記事タイトル一覧・description一覧の作成方法
上図は、JupyterLabでPythonコード:03_description.ipynbを開いた状態です。
一番上のセルにカーソルを移動し、「Shift+Enter」することで、各セルのコードが実行され、02_url.csvを読み取り、各記事のURLのhtmlを参照し、そこに記載されている、
- 記事公開日
- 記事最終更新日
- 記事タイトル
- description内容
を、03_description.csvに出力します。
上図は、03_description.csvの一例です。
03_description.csvで、自分のブログの公開中記事一覧を簡単に知ることができます。
WordPressでも記事一覧を見ることができますが、次ページへの画面切り替えが非常に遅いです。
03_description.csvを眺めていると、以下の気付きが出てくると思います。
- 記事タイトルの改善点
- descriptionの改善点
改善点とは、例えば、
- キーワードが入っているか?
- 読者が困っている点は明確か?
- この記事を読むとどのように解決するのか?
などです。
気付き次第、記事をリライトすれば、数か月後に検索順位が上がる可能性があります。
記事タイトル一覧・htagタイトル一覧の作成方法
上図は、JupyterLabでPythonコード:04_htag.ipynbを開いた状態です。
一番上のセルにカーソルを移動し、「Shift+Enter」することで、各セルのコードが実行され、02_url.csvを読み取り、各記事のURLのhtmlを参照し、そこに記載されている、
- 記事タイトル
- description内容
- htagタイトル
を、04_htag_list.csvに出力します。
上図は、04_htag_list.csvの一例です。
04_htag_list.csvのhtagタイトル(上図赤字箇所)眺めていると、以下の気付きが出てくると思います。
- htagタイトルにキーワードが漏れていないか?
- 下位階層htagタイトルは上位階層htagタイトルの範疇から外れていないか?
- htagの階層関係に矛盾がないか?(h3の直下にh5やh2がないか?)
気付き次第、記事をリライトすれば、数か月後に検索順位が上がる可能性があります。
尚、各ブログ記事毎のhtagタイトル一覧については、Google Chrome拡張機能「META SEO inspector」でも確認することができますが、公開中の全ての記事のhtagタイトル一覧を作成しようとすると膨大な時間がかかってしまいます。
各Pythonコード
「記事タイトル一覧・description一覧」と「記事タイトル一覧・htagタイトル一覧」を作成するために必要となる、Pythonコードは以下のとおりです。
参考になるようでしたら、使ってみてください。
MyBlogSite.zip ←ダウンロード用zipファイル(5KB)
尚、参照先sitemap.xmlのURLをライバルサイトのURLに書き換えることで、競合サイトのdescription一覧やhtagタイトル一覧を作成することが理論上は可能ですが、競合サイトのサーバに負荷がかかるため、自己責任でお願いします。
00_library_install.ipynb
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
]
}
],
"source": [
"# ブラウザを自動操作するsleniumライブラリのインストール\n",
"!pip install selenium"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
]
}
],
"source": [
"# HTMLおよびXMLドキュメントを解析するbeautifulsoupライブラリのインストール\n",
"!pip install beautifulsoup4"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.8"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
01_Sitemap.ipynb
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"from bs4 import BeautifulSoup\n",
"import requests"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"from selenium import webdriver\n",
"import re\n",
"import numpy as np\n",
"import pandas as pd"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"f = open('01_xml.csv', 'w')"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"# 調査対象サイトマップのURL設定\n",
"url = 'https://xxxxxx/sitemap.xml'\n",
"res = requests.get(url)"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"soup = BeautifulSoup(res.text,\"html.parser\")"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"# 全てのlocタグをloc_listへ取り込み\n",
"loc_list = soup.find_all('loc')"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"xml_list = []"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"# locタグ内の文字をxml_listへ取り込み\n",
"for i in loc_list:\n",
" xml_list.append(i.string)"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"# xml_list"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [],
"source": [
"# xml_listをデータフレームdf_xmlへ取り込み\n",
"df_xml = pd.DataFrame({'XML':xml_list})"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [],
"source": [
"# df_xml"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
"# データフレームdf_xmlをcsvファイルへ出力\n",
"df_xml.to_csv('01_xml.csv' , index=False)"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [],
"source": [
"f.close()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.8"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
02_article_list.ipynb
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"from bs4 import BeautifulSoup\n",
"import requests\n",
"import urllib.request as req"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"from selenium import webdriver\n",
"import re\n",
"import numpy as np\n",
"import pandas as pd\n",
"import time\n",
"import os\n",
"import datetime"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"f = open('02_url.csv', 'w')"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"# Sitemap.ipynbで作成した01_xml.csvをdf_xmlへ取り込み\n",
"df_xml = pd.read_csv('01_xml.csv')"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"# df_xmlのXMLの列をur_listへ取り込み\n",
"url_list = df_xml['XML']"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"url_list_j = []"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"for i in url_list:\n",
" res = requests.get(i)\n",
" time.sleep(1)\n",
" soup = BeautifulSoup(res.text,\"html.parser\")\n",
" # 全てのlocタブをloc_listへ取り込み\n",
" loc_list = soup.find_all('loc')\n",
" url_j = []\n",
" for j in loc_list: \n",
" url = j.string\n",
" url_list_j.append(url)"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"df_url = pd.DataFrame({'URL':url_list_j})"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"df_url.to_csv('02_url.csv' , index=False)"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [],
"source": [
"f.close()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.8"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
03_description.ipynb
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"from bs4 import BeautifulSoup\n",
"import requests\n",
"import urllib.request as req"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"from selenium import webdriver\n",
"import re\n",
"import numpy as np\n",
"import pandas as pd\n",
"import time\n",
"import os\n",
"import datetime"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"f = open('03_description.csv', 'w')"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"df_xml = pd.read_csv('02_url.csv')"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"url_list = df_xml['URL']"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"outdata_list = []\n",
"for i in url_list:\n",
" res = requests.get(i)\n",
" time.sleep(1)\n",
" soup = BeautifulSoup(res.text,\"html.parser\")\n",
" # タイトル文字列の抽出\n",
" title = soup.title.string\n",
" # description文字列の抽出\n",
" description_1 = soup.find_all(\"meta\" , attrs={'property' : 'og:description'})[0]\n",
" description = description_1.get('content')\n",
" # published_time文字列の抽出\n",
" published_time_1 = soup.find_all(\"meta\" , attrs={'property' : 'article:published_time'})[0]\n",
" published_time_2 = published_time_1.get('content')\n",
" published_time_3 = published_time_2[0:10]\n",
" # modified_time文字列の抽出\n",
" modified_time_1 = soup.find_all(\"meta\" , attrs={'property' : 'article:modified_time'})[0]\n",
" modified_time_2 = modified_time_1.get('content')\n",
" modified_time_3 = modified_time_2[0:10]\n",
" # \n",
" outdata_list.append([published_time_3 , modified_time_3 , title , description])"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"outdata = pd.DataFrame(outdata_list,columns=['published_time','modified_time','title','description'])"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"outdata.to_csv('03_description.csv' , index=False ,encoding='utf_8_sig')"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"f.close()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.8"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
04_htag.ipynb
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"from bs4 import BeautifulSoup\n",
"import requests\n",
"import urllib.request as req"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"from selenium import webdriver\n",
"import re\n",
"import numpy as np\n",
"import pandas as pd\n",
"import time\n",
"import os\n",
"import datetime"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"f = open('04_htag_list.csv', 'w')"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"df_xml = pd.read_csv('02_url.csv',encoding='utf-8_sig')"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"url_list = df_xml['URL']"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"f.write(\"番号,title,description,h1,h2,h3,h4,h5\" + \"\\n\")\n",
"cnt = 0"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"for i in url_list:\n",
" cnt += 1\n",
" res = requests.get(i)\n",
" time.sleep(1)\n",
" soup = BeautifulSoup(res.text,\"html.parser\")\n",
" title = soup.title.string\n",
" # 番号をcsvへ書き込み\n",
" f.write('%d,' % cnt)\n",
" # タイトルをcsvへ書き込み\n",
" f.write('\\\"%s\\\"\\n' % title)\n",
" description_1 = soup.find_all(\"meta\" , attrs={'property' : 'og:description'})[0]\n",
" description = description_1.get('content')\n",
" # descriptionをcsvへ書き込み\n",
" f.write(',,\\\"%s\\\"\\n' % description)\n",
" for j in soup.find_all([\"h1\", \"h2\", \"h3\" , \"h4\" , \"h5\"]):\n",
" # h1~h5タグの文字列をcsvへ書き込み\n",
" if j.name == \"h1\":\n",
" # h1 = j.text.strip()\n",
" h1 = j.string\n",
" f.write(',,,h1,\\\"%s\\\"\\n' % h1)\n",
" if j.name == \"h2\":\n",
" h2 = j.string\n",
" f.write(',,,,h2,\\\"%s\\\"\\n' % h2)\n",
" if j.name == \"h3\":\n",
" h3 = j.string\n",
" f.write(',,,,,h3,\\\"%s\\\"\\n' % h3)\n",
" if j.name == \"h4\":\n",
" h4 = j.string\n",
" f.write(',,,,,,h4,\\\"%s\\\"\\n' % h4)\n",
" if j.name == \"h5\":\n",
" h5 = j.string\n",
" f.write(',,,,,,,h5,\\\"%s\\\"\\n' % h5)\n",
" f.write(\"\\n\")"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"f.close()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.8"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
まとめ
ブログを運営している人で、公開中記事の、
- 記事公開日
- 記事最終更新日
- 記事タイトル
- description内容
- htagタイトル
などの一覧が必要な場合は、この記事で解説した方法で簡単に無料で作成することができます。
簡単に作成するためには、最初に一回だけ、Pythonコードの実行環境を構築する必要があります。
Python未経験者でも、Youtubeの「キノコード / プログラミング学習チャンネル」さんの動画に従って、無料で簡単に構築できます。
私自身、Python未経験者ですが、簡単に環境構築できました。
作成した「記事タイトル一覧・description一覧」と「記事タイトル一覧・htagタイトル一覧」を眺めると、記事の読者満足度向上や検索順位向上に向けた改善点に気付くことがあると思います。
気付き次第、記事をリライトすれば、数か月後に検索順位が上がる可能性があるので、試してみてください。
競合サイトの分析にも応用できますが、競合サイトのサーバに負荷がかかるため、自己責任でお願いします。
では、また。
コメント