#状況
pythonでpandasを使い、複数サイトでスクレイピングを行って、最終的にCSVを吐き出すプログラムを書いています。
まず、main.pyで以下のように関数の外でdfを宣言します。このdfは正常に作成されています。
columns = ["Name", "Price", "Url"] df = pd.DataFrame(columns=columns)
次に、一つ目の関数では、ECサイトの検索〜スクレイピングを行って、以下のような感じでdfに値を追加していきます。
nameは商品名、priceに値段、URLはその商品ページのURLです。
name | price | Url |
---|---|---|
hoge | hoga | hogu |
huga | hoga | huge |
次の関数では、このdfからurlを取り出し、そのURLに飛んで、その商品のIDを取得した上で、このdfにIDの列とそれぞれの値を追加したいです。
|name |price |Url |ID|
|---|---|---|
|hoge |hoga |hogu |abc|
|huga |hoga |huge |def|
この後もIDを使ってさらに別サイトでスクレイピングしていきたいため、dfをグローバルで扱いたいと思っていますが、そもそも上にあげた二つの処理すらうまくいっていません。
Traceback
1Traceback (most recent call last): 2 File "main.py", line 14, in <module> 3 gethogeSearch.search_hoge(search_word, get_pages) 4 File "/hoge/gethogeSearch.py", line 102, in search_hoge 5 print(df) 6NameError: name 'df' is not defined
#(2019/11/27追記)試したこと
グローバル変数としてではなく、main.pyで指定した上で各モジュールには引数渡しをする
main
1import pandas as pd 2import gethogeSearch 3 4#各関数で共有するグローバル変数/最終成果物のcsvのモト 5columns = ["Name", "Price", "Url"] 6df = pd.DataFrame(columns=columns) 7 8#実行時にターミナルから叩く 9search_word = input('検索する語句:') 10number = input('ページ数:') 11get_pages = int(number) 12 13df = gethogeSearch.search_hoge(df, search_word, get_pages) 14 15print(df) 16
gethogesearch
1#coding UTF-8 2 3import requests 4from bs4 import BeautifulSoup 5import pandas as pd 6import csv 7from time import sleep 8import random 9import lxml.html 10 11def search_hoge(df, search_word, get_pages): 12 13 14 #検索ワードからスクレイピング対象URL(=url)生成(略) 15 16 page = 1 17 18 try: 19 #「get_pages」のページ分だけ繰り返す 20 while page < get_pages + 1: 21 22 #何ページ目を取得している最中なのか表示 23 print(page,"ページを取得中.....") 24 headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36'} 25 26 #作成したURLからHTMLを取得 27 response = requests.get(url, headers=headers) 28 sleepTime = random.randint(2,8) 29 30 31 #BeautifulSoupの初期化 32 soup = BeautifulSoup(response.content, "lxml") 33 34 #検索結果リスト全体 35 items = soup.select(".hoge") 36 37 #リスト各要素に対して 38 for item in items: 39 name = item.find("span", {"class":"huga"}) 40 price = item.find("span", {"class":"hoge"}) 41 #空でないならdfに追加 42 if name != None and price != None: 43 nameTitle = name.string 44 priceText = price.string 45 item_url = item.a.get("href") 46 se = pd.Series([nameTitle, priceText, item_url], columns) 47 print(se) 48 df = df.append(se, columns) 49 50 #ページの下の方の「次のページ」のURLを取得 51 NextUrl = soup.find('li', {"class":"hg"}) 52 Url = NextUrl.a.get("href") 53 url = huga + Url 54 55 #次のページに行くので変数pageの値を1大きくする 56 page += 1 57 sleepTime = random.randint(3,15) 58 sleep(sleepTime) 59 except: 60 #取得しようと思ったページ数まで到達する前に終わったらそのページ以降はなかったと出力 61 nextpage = str(page+1) 62 print(nextpage + "以降のページはなかった") 63 64 finally: 65 #保存するcsvのファイル名を決める 66 filename = search_words + ".csv" 67 68 #作成したリストをcsvへ 69 df.to_csv(filename, encoding = 'utf-8-sig') 70 71 print("対象としたURL:" + url) 72 73 #終わったことを出力 74 print(filename + "を作成しました") 75 76 return df #empty dataframe
#教えていただきたいこと
なぜ引数渡しができていないのでしょうか。
回答3件
あなたの回答
tips
プレビュー