Webスクレイピングとは?
様々なWebサイトから情報を抽出・取得する技術です。
Googleの検索エンジンが、あなたのサイトを巡回して情報を取得していくのも、Webスクレイピングといっていいでしょう、きっと。
Webサイトの特定の情報を自動で取得し一覧化や分析までを助ける技術がスクレイピングと、ここでは紹介させていただきます。
スクレイピングのご注意
基本的に他のサイトに負荷をかけます。
そのため利用規約などで明確にスクレイピングを禁止しているサイトへのスクレイピング行為は、法的にも問題があります。
またスクレイピング対策をしているサイトへ無理やりスクレイピングをするのも、悪質な行為とご認識ください。
スクレイピングの依頼でよくあるご要望
どこかのサイトに自動でログインし、内容を監視する。
ある条件でショップのデータを集める。
特定サイトへの自動入力と自動操作。
note記事のWebスクレイピングをする理由
note記事のリライティングをしたい。
そのためにnoteの記事タイトル一覧が欲しい。
note記事のWebスクレイピング|実際のプログラミング
from google.colab import drive drive.mount('/content/drive/') %cd "drive/My Drive/note_backup" !apt-get update !apt install chromium-chromedriver !cp /usr/lib/chromium-browser/chromedriver /usr/bin !pip install selenium from bs4 import BeautifulSoup from selenium import webdriver from selenium.webdriver.chrome.options import Options from selenium.common.exceptions import TimeoutException from selenium.webdriver.support import expected_conditions as ec from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.common.by import By import numpy as np import pandas as pd pd.set_option('display.max_columns', 500) pd.set_option('display.max_rows', 500) import csv from datetime import datetime from time import sleep import os, time import json import requests import math urllist = [] urllist = ['ここを自分のダッシュボードのURLに'] print(urllist) #######自分の公開記事は何記事かをpost_numに入れる####### post_num = 200 post_math = math.ceil(post_num/6) urllist = [] df_concat = pd.DataFrame(index=[]) for i in range(1,post_math): url = 'https://note.com/api/v2/creators/mkp_consulting/contents?kind=note&page=' + str(i) + '&disabled_pinned=false' urllist.append(url) def DF_MAKE(urllist): html = "" options = webdriver.ChromeOptions() options.add_argument('disable-infobars') options.add_argument('--no-sandbox') options.add_argument('--headless') options.add_argument('--window-size=1024,768') user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.157 Safari/537.36" options.add_argument(user_agent) driver = webdriver.Chrome(options=options); driver.implicitly_wait(30) driver.set_page_load_timeout(30) j = 0 while j < 9: try: driver.get(urllist) print("The page was loaded") except TimeoutException: j = j + 1 print("Timeout, Retrying... (%(j)s/%(max)s)" % {'j': j, 'max': 9}) time.sleep(10) continue else: break print("-----------------------------------------------------------------") html = driver.page_source Tag = driver.find_element_by_tag_name('pre').get_attribute('innerText') json_dict = json.loads(Tag) df = pd.DataFrame(json_dict["data"]["contents"]) if df.empty: return return df for i in range(len(urllist)): sleep(5) print(i,len(urllist),urllist[i]) df = DF_MAKE(urllist[i]) if df.empty: break else: df_concat = pd.concat([df_concat,df]) df_concat.to_csv('note_list_backup.csv') print('end')
note記事のWebスクレイピング|準備
▽GoogleDriveにフォルダ作成
GoogleDrive直下にnote_backupというフォルダがある前提です。
▽noteダッシュボードのURL
自身のnoteダッシュボードのURLを取得しておいてください。
▽note記事の公開記事数を入れる
Webスクレイピングの動作後の結果
GoogleDriveのnote_backupフォルダに、CSVファイルが作成されます。
Colaboratory環境【ファイル添付有】【記事一覧取得補正版】
note公開記事の総数取得用pythonコード。
単純にJSONファイルを呼び出して、総数が格納されているところへアクセス。
def func_totalCount(url_id): import requests import json #JSONの取得 json_res = requests.get('https://note.com/api/v2/creators/' + url_id + '/contents?kind=note&page=1&disabled_pinned=false') data = json_res.json() print(json.dumps(data, indent=4)) json_dict = json.dumps(data, indent=4) totalCount = data['data']['totalCount'] print(totalCount) return totalCount
note記事URLの作成
def num_kiji(url_id,totalCount): #######自分の記事は何記事####### post_math = math.ceil(totalCount/6) urllist = [] df_concat = pd.DataFrame(index=[]) for i in range(1,post_math): url = 'https://note.com/api/v2/creators/' + url_id + '/contents?kind=note&page=' + str(i) + '&disabled_pinned=false' urllist.append(url) return urllist
注意
自分のnoteダッシュボードからIDらしきものを入れる。
たまに失敗するが、再度、時間間隔を開けて実行すると成功する。
あまりいたずらに作動させてしまうと、note側に負荷がかかります。
url_id = 'mkp_consulting' print(url_id)
ここまでのプログラム全体
私自身がプログラマではないため、修正点やおかしなところは多々あるかと思いますが、以下で共有公開しておりますのでご参考になさってください。
from google.colab import drive drive.mount('/content/drive/') %cd "drive/My Drive/note_backup" !apt-get update !apt install chromium-chromedriver !cp /usr/lib/chromium-browser/chromedriver /usr/bin !pip install selenium from bs4 import BeautifulSoup from selenium import webdriver from selenium.webdriver.chrome.options import Options from selenium.common.exceptions import TimeoutException from selenium.webdriver.support import expected_conditions as ec from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.common.by import By import numpy as np import pandas as pd pd.set_option('display.max_columns', 500) pd.set_option('display.max_rows', 500) import csv from datetime import datetime from time import sleep import os, time import json import requests import math url_id = 'mkp_consulting'#@param {type:"string"} def DF_MAKE(urllist,totalCount): html = "" j = 0 while j < 9: try: driver.get(urllist) print("The page was loaded") except TimeoutException: j = j + 1 print("Timeout, Retrying... (%(j)s/%(max)s)" % {'j': j, 'max': 9}) time.sleep(10) continue else: break print("-----------------------------------------------------------------") html = driver.page_source Tag = driver.find_element_by_tag_name('pre').get_attribute('innerText') json_dict = json.loads(Tag) df = pd.DataFrame(json_dict["data"]["contents"]) if df.empty: return return df def func_totalCount(url_id): #JSONの取得 json_res = requests.get('https://note.com/api/v2/creators/' + url_id + '/contents?kind=note&page=1&disabled_pinned=false') data = json_res.json() print(json.dumps(data, indent=4)) json_dict = json.dumps(data, indent=4) totalCount = data['data']['totalCount'] print(totalCount) return totalCount def num_kiji(url_id,totalCount): #######自分の記事は何記事####### post_math = math.ceil(totalCount/6) urllist = [] df_concat = pd.DataFrame(index=[]) for i in range(1,post_math): url = 'https://note.com/api/v2/creators/' + url_id + '/contents?kind=note&page=' + str(i) + '&disabled_pinned=false' urllist.append(url) return urllist totalCount = func_totalCount(url_id) urllist = num_kiji(url_id,totalCount) df_concat = pd.DataFrame() options = webdriver.ChromeOptions() options.add_argument('disable-infobars') options.add_argument('--no-sandbox') options.add_argument('--headless') options.add_argument('--window-size=1024,768') user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.157 Safari/537.36" options.add_argument(user_agent) driver = webdriver.Chrome(options=options); driver.implicitly_wait(30) driver.set_page_load_timeout(30) for i in range(len(urllist)): sleep(5) print(i,len(urllist),urllist[i]) df = DF_MAKE(urllist[i],totalCount) if df.empty: break elif df_concat.empty: df_concat = df else: df_concat = pd.concat([df_concat,df]) df_concat.to_csv('note_list_backup.csv') print('end')
以下ファイルに関してはノークレームノンサポートですが、質問あれば随時お問い合わせからご連絡ください。
わかる範囲でお答えます。
不完全な点|記事の総数取得部分を修正
予定
当サイトはリンクフリーです。
ご自身のブログでの引用、TwitterやFacebook、Instagram、Pinterestなどで当サイトの記事URLを共有していただくのは、むしろありがたいことです。
事前連絡や事後の連絡も不要ですが、ご連絡いただければ弊社も貴社のコンテンツを紹介させていただく可能性がございます。