質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

1回答

3599閲覧

URLリストのtxtを読み込んでスクレイピングして、取得した情報をcsvに保存したい

etherwind

総合スコア27

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

1クリップ

投稿2018/06/17 14:43

編集2023/01/09 19:17

前提・実現したいこと

目当てのサイトから必要な情報を抜き出し、csvに保存するところまではできたのですが、実際にやりたいことまで知恵が及ばず、こちらで質問することにしました。

下記コードで1つのURLの"h2"が取得でき、"news.csv”に保存ができています。
でも本当は、情報を取得したいURLが大量あるのです。

該当のソースコード

現在のコード(sample.py)
──────────

import requests, bs4 import csv res = requests.get('https://news.yahoo.co.jp/pickup/6286588') res.raise_for_status() soup = bs4.BeautifulSoup(res.text, "html.parser") elems = soup.select('h2') for elem in elems: print(elem) with open('news.csv', 'w', encoding='CP932', errors='ignore') as f: writer = csv.writer(f) writer.writerows(elems)

──────────

本題

URLは違うけど、同じサイトの中で、hmtlの骨組みが同じなので、アクセスするURLさえ変えることができれば他はそのままでいいです。

そこで、「URLがリスト化されたファイル"urllist.txt"の内容を読み込んで、一行目のURLから順々にアクセスして"h2"を取得し、csvに書き込んで保存するコード」というイメージでコーディングしたいと思っています。

※urllist.txtの内容
https://news.yahoo.co.jp/pickup/6286588
https://news.yahoo.co.jp/pickup/6286594
https://news.yahoo.co.jp/pickup/6286582

"requests.get"で指定するURLを別のファイルから読み込んで指定する方法、同じ処理を繰り返す方法、などで調べたのですが、必要な回答に辿り着くことができませんでした。
正解例がわかる方、どなたかお願いしますm(__)m

補足情報

・URLとh2に関しては質問用です。
・urllist.txtはテキストファイルじゃなくてもいいです。
・requests.getにこだわりはないです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

データを読み取る部分を関数にすると良いでしょう。

Python

1import time 2...3 4 5def scrape(url): 6 res = requests.get(url) 7 ...8 9 time.sleep(1) # 一秒待つ。相手方のサーバに負担をかけすぎないための配慮。 10 11 12def main(): 13 ファイルからidを読み込み、page_id_listを作る 14 for page_id in page_id_list: 15 scrape(f'https://news.yahoo.co.jp/pickup/{page_id}') 16 17 18if __name__ == '__main__': 19 main()

肝心の『ファイルからidを読み込む』部分は、例えば次のように書けます。

plain

16286588 26286594 36286582

Python

1with open('id_list.txt') as f: 2 page_id_list = [int(row) for row in f]

追記

順調なようなので、追加で少しお手伝い。
ファイルに書き出す方法は、主に次の二つのうちいずれかです。

  • csvライターをやり取りする方法

Python

1def scrape(url, csv_writer): 2 ...3 4 csv_writer.writerows(elems) 5 6 7def main(f): 8 writer = csv.writer(f) 9 10 ...11 for page_id in page_id_list: 12 scrape(f'https://news.yahoo.co.jp/pickup/{page_id}', writer) 13 14 15if __name__ == '__main__': 16 with open('news.csv', 'w', encoding='CP932', errors='ignore') as f: 17 main(f)

毎回開きなおすと上書きされてしまうことにご注意ください。

  • 結果をリストにまとめておく方法

Python

1def scrape(url): 2 ...3 4 5def main(): 6 result = [] 7 8 ...9 for page_id in page_id_list: 10 result.extend(scrape(f'https://news.yahoo.co.jp/pickup/{page_id}')) 11 12 with open('news.csv', 'w', encoding='CP932', errors='ignore') as f: 13 writer = csv.writer(f) 14 f.writerows(result)

コードの書き方について

teratailには、上記のようにコードを見やすく表示する機能があります。
質問編集画面を開き、コードを選択した状態で<code>ボタンを押してください。
Python

投稿2018/06/17 14:51

編集2018/06/18 06:13
LouiS0616

総合スコア35658

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

etherwind

2018/06/17 15:07

素早いご回答ありがとうございます。早速試しているのですがうまくいかず、もしできたら完成形のコードで書き込んでいただければ幸いですm(_ _)m
LouiS0616

2018/06/17 15:09

インデントさえ気を付ければ、ほとんど元のコードのままで動くはずですよ。 なにかエラーが出ているのでしょうか?
etherwind

2018/06/17 15:16

実は、pythonの勉強は今日始めたばかりで、単純に、教えてくださったコードを、自分のコードのどこに書き加えて、どこを書き換えるのか、まだ知識不足でわからないからですm(_ _)m 「データを読み取る部分を関数にする」の意味はわかりました。いま「def scrape」や「def main」の使い方や、パラメータを関数にする場合のやり方などを調べています(汗)
LouiS0616

2018/06/17 15:29

なるほど。 『scrape』というのは今私がテキトーにつけた名前なので、ヒットしないです。 『Python 関数』とか調べてみてください。
etherwind

2018/06/17 15:30

ありがとうございます。頑張ってみますm(_ _)m
etherwind

2018/06/17 16:12

コードの見た目を直しました(;^ω^)
etherwind

2018/06/18 05:59

途中経過です。 とりあえずid_list.txtを読み込んで情報を取得するところまでいけました。 あとはcsvへの保存のみです。 ────── import requests, bs4 import csv import time def scrape(url): res = requests.get(url) res.raise_for_status() soup = bs4.BeautifulSoup(res.text, "html.parser") elems = soup.select ('h2') for elem in elems: print(elem) time.sleep(1) def main(): with open('id_list.txt') as f: page_id_list = [int(row) for row in f] for page_id in page_id_list: scrape(f'https://news.yahoo.co.jp/pickup/{page_id}') if __name__ == '__main__': main() #with open('news.csv', 'w', encoding='CP932', #errors='ignore' newline="") as f: # writer = csv.writer(f) # writer.writerows(elems)
LouiS0616

2018/06/18 06:14

順調なようですね。素晴らしいです。少しだけ追記しておきました。
etherwind

2018/06/18 06:17

ありがとうございます。追記していただいたコードをみました。あぁまさにこれで、ちょうどいま「= []」という、リスト化する時に使うらしいコードの使い方を調べていたところです! 保存が上手く行かないので、とりあえずデータの取得までで仕上げたのが上の途中経過のものになります。引き続き、頑張ります。
etherwind

2018/06/18 07:21 編集

できました! 「csvライターをやり取りする方法」を参考にしました。 commandプロンプト上で情報を取得している流れが見たかったので11行目に「print(elem)」を追記しています。 ここから細かい調整をしていきますが、ひとまず、実現したい事はできたので、一旦クローズにします。 「LouiS0616」さんありがとうございました! ────────── import requests, bs4 import csv import time def scrape(url, csv_writer): res = requests.get(url) res.raise_for_status() soup = bs4.BeautifulSoup(res.text, "html.parser") elems = soup.select ('h2') for elem in elems: print(elem) csv_writer.writerows(elems) time.sleep(1) def main(f): writer = csv.writer(f) with open('id_list.txt') as f: page_id_list = [int(row) for row in f] for page_id in page_id_list: scrape(f'https://news.yahoo.co.jp/pickup/{page_id}', writer) if __name__ == '__main__': with open('news.csv', 'w', encoding='CP932', errors='ignore') as f: main(f) ────────── ※余談 「結果をリストにまとめておく方法」だとどうしても「NoneType’ object is not iterable」が出てしまい、そちらは断念しました。いつかエラーが出てしまう原因を理解したいと思います。 エラーが出てしまうコードを一応載せておきます。 失敗パターン ────────── import requests, bs4 import csv import time def scrape(url): res = requests.get(url) res.raise_for_status() soup = bs4.BeautifulSoup(res.text, "html.parser") elems = soup.select ('h2') for elem in elems: print(elem) time.sleep(1) def main(): result = [] with open('id_list.txt') as f: page_id_list = [int(row) for row in f] for page_id in page_id_list: result.extend(scrape(f'https://news.yahoo.co.jp/pickup/{page_id}')) with open('news.csv', 'w', encoding='CP932', errors='ignore') as f: writer = csv.writer(f) f.writerows(result) if __name__ == '__main__': main()
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問