こんにちは!
先日プログラミングスクールを卒業しまして、10月半ばから受託の会社で働き始めた24歳!(拳で)
今回業務上でpythonを用いたscrapingをはじめて実装しまして、
まぁ時間が経つと忘れそうなので備忘録〜・・・
今回の学びをバネにもっと高みへいくぜ!!・・・・ということで
今回作ったscrapingAppの仕様について.py
Global_urls=[]
Global_log=[]
function(url)
#Global_logにurlを代入
パート①
#そのurlのhtmlテキストをget
#htmlテキストの中からaタグ群だけget
#aタグ群からhrefパラメータ群を抽出
#hrefパラメータ群の一律的な整形
#hrefパラメータ群をGlobal_urlsに代入
#Global_urlsに重複があれば重複削除
パート②
#for文でGlobal_urlsの中身を順番に取り出す(変数urlとして取り出す)
#Global_log内に当該urlがあればskip(functionにおいて処理済のurlがlogに貯まるので)
#functionを当該urlを引数に呼び出す(再帰関数)
# ここまででtopページのurlから、そのurlと関わりのある全てのurlを、Global_urlsに格納することができます
# これをファイルに書き出すなり、printするなりと好き放題できるようになります。
使ったモジュール.py
1: requests
#urlに対してrequestを送ることができる
#response= requests.get(url)→getアクションで送ってる
#response.textとすることでhtmlのテキスト情報が取れる
#response.status_codeと書くことでurlの有効性を調べることができる
2: lxml
#requestsのreturnをBeautifulSoupオブジェクトに変換する際に使用
#parserの一種(?)(要確認)
3: BeautifulSoup
#requestsのreturn(htmlのテキスト情報)から特定のタグを指定して収集・list化してくれる
#つまりhtmlのテキストの中からaタグのものだけ収集!list(配列)に順番に突っ込む!ということ出来る
#思ったより使いどころが少なかったので、使い方下手なのかも・・・
4: re
#pythonで正規表現を使う際に必要
5: urllib.parse
#urlをparseするのに必要
#https://qiita.com/drafts/4f6f4e3ad2d5048ced4f/edit
#上記を[scheme="https", netloc="qiita.com", path="/drafts/4f6f4e3ad2d5048ced4f/edit"]みたいに解析してくれる
#return値.pathとかってやると path="/drafts/4f6f4e3ad2d5048ced4f/edit"これだけ取れてくる便利
7: urllib.request
#requests.status_codeとほぼ同じ使い方、こちらは404がreturnで返るというより404の場合エラーが起きる
#response.status_codeに気づく前の名残。当時は例外処理で404エラーが出ればskipみたいな使い方をしていた
8: pdb
#デバッガー。ブレークポイント。 railsで言う所のbinding.pry laravelで言う所のeval(\Psy\sh())
9: sys
#再帰関数の再帰回数の上限を操作できる関数が入ってる
#ちなみにsys.setrecursionlimit(10000)これ
10: time
11: datetime
#10-11はまとめて紹介。datetime.datetime.fromtimestamp(time.time())
#こう書くと現在の時間が取れる。詳細はよく調べてないので割愛
12: pathlib
#path操作の為のモジュール。path内の拡張子が取りたかっただけなので使い方はparser的
#詳細はよく調べてないので割愛
13: unicodedata
#文字コードを変換してくれるモジュール。
#クエリ文字列に混じってる日本語に対してasciiじゃ対応できないよって言われたので組み込むことに
メモリ無視してわかりやすさ重視で書いていくYO
qiita上では変数めっちゃ使うってことです。
実際は変数少なめにコード書いてます。
パート1.py
Global_urls=[]
Global_log=[]
# ターゲットURL
# url= 'https://qiita.com'
def getLinksFromALink(url)
# このurlは処理したことがあるよって記録を残したいのでlogに追加
Global_log.append(url)
#urlへrequest送って、返ってきたresponse
response= requrst.get(url)
# urlのhtmlテキストをget
htmlText= response.text
# htmlテキストをBeautifulSoupのオブジェクトへ変換
SoupObject= BeatutifulSoup('htmlText', 'lxml')
# BeautifulSoup化したhtmlテキストの中からaタグ群だけget
aTags= SoupObject.findAll('a')
# aタグ群からhrefパラメータ群を抽出
# 抽出データをglobal_urlsへ
# ちなみにここで出てくるlinkは相対パスだったり、絶対パスだったり、.htmlという拡張子がついていたり、、、
# はたまたリンク切れのurlが紛れていたり、クエリ文字列が違うだけで同じlinkが何個も入ってきたり、、、etc
# と、色んな値が取れるのでこのfor文の真ん中らへんで別途作成した条件分岐及びlink再構成の関数を挟むとgood
#またドメインを指定する際もここで条件を挟むのがgood
for aTag in aTags:
link= aTag.get('href')
Global_urls.append(link)
#Global_urlsに重複があれば重複削除
# list内の重複削除をしてくれるdict.fromkeys、結果dict型になってしまうのでlist()で再びlist型に
Global_urls= list(dict.fromkeys(Global_urls))
パート2.py
for url in Global_urls:
#もし今回取り出されたurlと同じ値がlogにあればskip
if url in Global_log:
continue
# そうでなければもう一度この関数を呼び出す
# 再帰的に各urlと関わりのあるurlsをGlobal_urlsに格納し続ける
# 順次増え続けるGlobal_urlsの全てにアクセスし終えるまで関数は終わらない
getLinksFromALink(url)
#全てが終わればGlobal_urlsをreturnする
return Global_urls
# あとはこのurls達をファイルに書き出したり、printしたりする
# 自分はファイルに書き込んだので後日それもまとめる
改めて
だいぶ端折ってますが、大枠で言えばこんな感じの関数を作ってました。
この後のファイル作成とか、遭遇したエラーとかについては来週中にまとめようと思いますー
function.py
Global_urls=[]
Global_log=[]
def getLinksFromALink(url)
Global_log.append(url)
response= requrst.get(url)
htmlText= response.text
SoupObject= BeatutifulSoup('htmlText', 'lxml')
aTags= SoupObject.findAll('a')
for aTag in aTags:
link= aTag.get('href')
Global_urls.append(link)
Global_urls= list(dict.fromkeys(Global_urls))
for url in Global_urls:
if url in Global_log:
continue
getLinksFromALink(url)
return Global_urls