LoginSignup
4
1

More than 1 year has passed since last update.

( ^ω^)は突貫スクレイピングを強いられてるようです

Posted at

こちらの続きです
※ここに書かれている内容は( ^ω^)が初心者以外実際の企業・人物・団体には関連ございません。
※相変わらず初心者がPythonに翻弄されているだけで1ミリも為にならないと思います。

~簡単な前回のあらすじ~

( ^ω^)は上司から転職初日に1行1時間かかるという伝説のExcel表埋めを強いられた。
( ^ω^)は合計で2500行以上もある事に発狂しかけ、夜中に雄叫びをあげながらスクレイピングに逃げたのだった・・・

いんとろだくしょん

(´・ω・`)「おー!? なにこれ!?!?」

( ^ω^)「日曜日暇だったから作ったお、長岡賃貸サイトからこういう風にとれたお。1件ずつcsvになっちゃったけどExcel使えば一括で取り込み出来るし横持ちも出来るんじゃないかお(適当)」

(´・ω・`)「すごいね!! じゃあ他のも取れる? この検索サイトからできればとってきてほしいなあ! ここ老舗だから情報多いんだよね!」(PCチラッ)

( ^ω^)「やれるかわからないけど2500時間は嫌だからチャレンジしてみるお、えーとF12を押して・・・」

(;^ω^)「うわっ、なんだおこのサイト!! まずソースがdivダグまみれでクッソ汚くて読みづらいお!! しかもURLの末尾が激しくクソみたいな文字の羅列だお! 前回やった数字ループでお手軽取得できないお! というかマジで汚えコードだなこのサイト!!(うわあ・・・多分できると思います)」

(´・ω・`)「は?

( ^ω^)「地に頭を付けて平に平に有り難く業務を行いますお


とりあえず書く

(;^ω^)「今回ショボン先輩から言われたサイトにもスクレイピングしないでね、とは書いてなかったお、けどちゃんとサーバーに負荷がかからないようにしっかりtimeさんを使って制御するお」

( ^ω^)「・・・・」

(;^ω^)「前回は全部欲しい情報がテーブルひとつにあったから楽を出来たけど、このサイトまず欲しい情報をソースから探すのに一苦労だったお・・・明日からブーンも先生のところに行ってお世話になるけど、やがて書いていいよって言われたら、こういう他人が読んでもわからないコードは書かないようにしないといけないお」

( ^ω^)「ま、でも今回のも自分だけしか見ないし、やらんもんだからざっくりやっちゃうお」

( ^ω^)「今回は末尾がループじゃないけれども1つのページに欲しい県の情報が全部網羅されてるお、なのでこの最初のページから全部のURLを抜いてリストに入れてループ材料にするお」

( ^ω^)「とりあえずちゃんと1ページから欲しいものが取れるか中身を書くお」

~1時間ほど時間が過ぎ~

(;^ω^)「欲しい情報がテーブルどころか地獄のdivダグ祭りの中にあって初心者のブーンには大変だったお、しかも何度も同じセレクタを使うんじゃないお、初心者殺しだお

test.py
    shop_name = soup.find(class_="vipstar")
    shop_name = shop_name.find("h1")

( ^ω^)「とりあえず店舗名はたくさん使われてるセレクタの中でもh1タグにあったお、これを名前として取得するお」

( ^ω^)「ざっと800ページ取らないといけないからページ確認は2~3枚しかしてないけど多分全部h1タグにあるお(フラグ)

( ^ω^)「こんな感じであるだろう運転で売買料金や賃料もとっていって・・・」

test.py
    main = []
    main.append(shop_name)
    main.append(shop_rate)

    for item in other_rate:
        main.append(item)

    for item in main_deta:
        main.append(item)

( ^ω^)「最終的にはmainにリストとして全部格納するお、これをpandas先生を使って、雑に店舗名をファイル名にしたcsvにするお~」

(;^ω^)「ちなみにサイトが古すぎたせいかわからないけど最初サイトをsoupに煮込んだとき、文字化けしてビックリして椅子から転げ落ちたお」

test.py

<requests.getしたもの>.encoding = <requests.getしたもの>.apparent_encoding

( ^ω^)「調べたらUTF-8になおしてくれるエンコードさんを見つけたお、グーグル先生様々だお~」

( ^ω^)「3ページくらいテストで取得してcsvにした結果ちゃんと欲しいのがとれたお! 次はこれをループさせるために親ページから取り出したいページのリンク達を取得してくるお」

原因不明の取得

test.py

link_map = soup_map.find_all(class_ = "vipkarakita" )

map_list =[]

for maps in link_map:
    maps = maps.find("a")
    maps = maps.get("href")
    map_list.append(maps)

(;^ω^)「このクソサイトのありがたいポイントは欲しいリンクが全部同じセレクタだったことだお・・・見つけ出した時は思わずガッツポーズしちゃったお・・・」

(;^ω^)「春のdiv祭り~もう二度とやりたくありません~

( ^ω^)「とにもかくにもこれでちゃんとリストとしてとれてるはずだお~! 確認だお!」

test.py
for link in map_list:
    url = link
    print(url)
#結果
  ../2ch/kara/kimasita/dfeifbseje.html
  ../2ch/kara/kimasita/feiwbfwlefwefn.html
  ../2ch/kara/kimasita/dneibwdmeobel.html
  ../2ch/kara/kimasita/kownwbqosmabw.html
  ../2ch/kara/kimasita/diwbdaowmwbaieje.html

( ^ω^)「?????」

( ^ω^)「なんか相対パスみたいに先頭にドット2個ついてるお?」

( ^ω^)「print()で見たからかお? でも他のサイトで色々見た時はみんな"http:~"がついててフルパスだったお・・・どうしてだお?」

( ^ω^)「わからんけどまわしてみるお?」

( ^ω^)「ほげ!?

test.py
##クソ長エラー文の末尾

\model.py in prepare_url(self, url, params)
    388             error = error.format(to_native_string(url, 'utf8'))
    389 
--> 390             raise MissingSchema(error)
    391 
    392         if not host:

MissingSchema: Invalid URL '../2ch/karakimasita/dfeifbseje.html': No schema supplied. Perhaps you meant http://../2ch/karakimasita/dfeifbseje.html?

( ^ω^)「ふむふむ? Deepl先生に聞くお!! なになに?」

( ^ω^)「スキーマが無いーマwwwwwwwスキーマが無いおwwwwwwwww多分このURLだと思うけど?けど?wwwwwwwwwww

( ^ω^)「・・・・・」

( ^ω^)「Deeplに煽られてるのも慣れてきたお、、

( ^ω^)「スキーマ? ってなんだお? うーん、それっぽいのすぐ見つからないお。すぐ出て来ない場合は調べる時間がちょっと就業中だしもったいないお。とかく何らかの原因で感覚的にドット2個の前が省略されてるのはわかったお」

( ^ω^)「とりあえず動くように修正するお」

test.py

link_map = soup_map.find_all(class_ = "vipkarakita" )

map_list =[]

for maps in link_map:
    maps = maps.find("a")
    maps = maps.get("href")
    maps = maps.replace("..","")
    print(maps)
    map_list.append(maps)

( ^ω^)「前回もそうだけどリプレイスさんには感謝してるお、これで/2ch/karakimasita/~.htmlに変更できてるはずだお、確認するためにprint(maps)を添えたお」

test.py
#結果
/2ch/kara/kimasita/dfeifbseje.html
/2ch/kara/kimasita/feiwbfwlefwefn.html
/2ch/kara/kimasita/dneibwdmeobel.html
/2ch/kara/kimasita/kownwbqosmabw.html
/2ch/kara/kimasita/diwbdaowmwbaieje.html
#...以下略

( ^ω^)「よーしいけるお、これをループするたびに足りない分と結合させればいいお」

( ^ω^)「幸いここの省略されていた部分はドメイン部分だったお、同じ文字列だったから省略されたのかお? 帰ったら調べないとだお・・・」

( ^ω^)「ループさせるのは簡単だお~、Pythonはfor文が簡潔だお」

( ^ω^)「さてさてポチっとwwwwww稼働する様子見ながら午後の優雅なコーヒータイムだおwwwwwwwwww」

(;^ω^)「でも改めて見ると自分で書いたコードクッソ汚いおね・・・ループ処理部分が複数あるけども関数にして呼び出したほうが絶対綺麗だし読みやすいお、特にPythonはインデントでブロックが区切られてるから絶対そうしたほうが見る人に優しいお」

(;^ω^)「theベタ打ち丸出しで恥ずかしいお、というかジュピターノートブックでまた稼働させてるけどいい加減にsysさんとか使ってURLだけ渡して働かせるようにしないとだお、同じサイトであと同じようなこと都道府県回数するんだからそこもなんとかせな・・・」

エラーとの戦いの果て

(;^ω^)「結論いうとハチャメチャにエラーが出たお

( ^ω^)「まず店舗名がh1タグで取得するのにもともとのサイトが古すぎてブランクリンクがあったお、そこで止まったからif文で店舗名が取得出来ない場合は飛ばすようにしたお・・・ついでにcsvのファイル名に取得した店舗名を使ってたけどまさかのファイルにして保存したらシステムエラーになる文字を使ってると思わなかったお」

test.py
    if soup.find(class_="vipstar") is None:
        continue

    shop_name = soup.find(class_="vipstar")
    shop_name = shop_name.find("h1")
    shop_name = shop_name.get_text()
    shop_name = shop_name.replace("/","")
    shop_name = shop_name.replace("?","_")
    shop_name = shop_name.replace(">","_")
    shop_name = shop_name.replace("<","_")
    shop_name = shop_name.replace(".","_")

( ^ω^)「汚なッ!!!

( ^ω^)「これ絶対何かしらでループ処理できたけどPython触って2日目のブーンには難しかったお・・・リストに消し去りたい文字打ち込んでループささせて処理しようとしたけどむずかったお・・・人様のサイトをクソサイト呼ばわりしてたけどブーンの書いたコードのほうがよっぽど汚いおね・・・」

(;^ω^)「でもなんとか業務時間内に800件全部とれたお~」

( ^ω^)「足りない頭のブーンでも時間がかかったけど出来たお、Pythonのモジュールやライブラリのおかげだお! Pythonすごいお!」

( ^ω^)「Scrapyとかも気になるお、やってみたいお~」

( ^ω^)は突貫スクレイピングを強いられているようです 第一部完

(´・ω・`)「やあ、調子はどうだい?」

( ^ω^)「あ、ショボン先輩。言われてたサイトのこの県は全部取れたお、(バグらなければ)他の県も取り放題だお」

(´・ω・`)「おー! すごいね!! 先月までは会議で使う資料の完成に半年計画だったけどブーンのおかげですぐ終わりそうだ!! 助かるよ!!」

(;^ω^)「(半年計画で作る会議資料って何だお!? おかしくないかお!?!?)

( *^ω^)「(でも褒められると嬉しいおね)」

(´・ω・`)「じゃ、次はこのサイトね。次は画像付きで頼むよ

(;^ω^)「ほげ!?

今回で学んだこと

( ^ω^)「一回書いたコードで満足しないで時間があるときに処理を短くするとかわかりやすくするとかリメイクするの大事だお、、」

( ^ω^)「ただhtmlがちょっとわかって、手書きでコードがちょびっとかけるならPythonでスクレイピングはとっても楽しいお!!」

おしまい

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1