2017-08-30 1 views
2

Pythonの初心者ですが、実際にそれを学びたいと思っています。私はウェブサイトからデータを掻き集めて遊んでいましたが、私は解決策に近づいているように感じています。問題は、コードのURLが各繰り返しでページ番号を変更している場合でも、URLの最初のページだけを返すことです。Python - 複数のURLをカバーするWebスクレイピングデータテーブル

私が使用しているウェブサイトはhttp://etfdb.com/etf/SPY/#etf-holdings&sort_name=weight&sort_order=desc&page=1であると私はこすりしようとしている特定のデータテーブルがSPYホールディングスである(それは506の保有を言うし、その後などリンゴ、マイクロソフトが一覧表示されます場合)

あなたが気づくと、データテーブルには一連のページがあります(これはティッカーシンボルに基づいて変更されますが、SPYの場合は34ページありますが、必ずしも34ページになるわけではありません)。それは15社を表示することから始まり、次に2をクリックすると(次の15個の保有を見るために)、URLページ= 1が上がります。

#to break up html 
from bs4 import BeautifulSoup as soup 
from urllib.request import urlopen as uReq 
import csv 
import math 

#goes to url - determines the number of holdings and the number of pages the data table will need to loop through 
my_url = "http://etfdb.com/etf/SPY/#etf- 
holdings&sort_name=weight&sort_order=desc&page=1" 
uClient = uReq(my_url) 
page_html = uClient.read() 
uClient.close() 
page_soup = soup(page_html,"html.parser") 
#goes to url - scrapes from another section of the page and finds 506 holdings 
num_holdings_text = page_soup.find('span',{'class': 'relative-metric-bubble-data'}) 
num_holdings = num_holdings_text.text 
number_of_loops = int(num_holdings) 
num_of_loops = number_of_loops/15 
#goes to url - because the table shows 15 holdings at a time, this calcs number of pages I'll need to loop through 
num_of_loops = math.ceil(num_of_loops) 
holdings = [] 
for loop in range(1,num_of_loops+1): 
    my_url = "http://etfdb.com/etf/SPY/#etf-holdings&sort_name=weight&sort_order=desc&page=" + str(loop) 
    uClient = uReq(my_url) 
    page_html = uClient.read() 
    uClient.close() 
    page_soup = soup(page_html, "html.parser") 
    table = page_soup.find('table', { 
    'class': 'table mm-mobile-table table-module2 table-default table-striped table-hover table-pagination'}) 
    table_body = table.find('tbody') 
    table_rows = table_body.find_all('tr') 
    for tr in table_rows: 
     td = tr.find_all('td') 
     row = [i.text.strip() for i in td] 
     holdings.append(row) 
     print(row) 
    print (holdings) 


    with open('etfdatapull2.csv','w',newline='') as fp: 
     a = csv.writer(fp, delimiter = ',') 
     a.writerows(holdings) 

繰り返しますが、私が午前問題はそれだけで継続的に(例えば、それは常にちょうどリンゴを返します。 - GE)の最初のページを返していることにあるリンクを更新しているにもかかわらず。

ありがとうございました。再び、これは非常に新しいので、できるだけそれを黙ってください!

答えて

0

問題は、スクラップしようとしているサイトが実際にJavascriptでデータを読み込むことです。あなたはChromeデベロッパーツールのようなものを使用する場合は、2ページのものを見ることができ、サイトには次のリンク参照:

http://etfdb.com/data_set/?tm=1699&cond={by_etf:325}&no_null_sort=true&count_by_id=&sort=weight&order=desc&limit=15&offset=15

をお探しているデータがあります。あなたのロジックは健全ですが、上記のリンクを掻き取るだけです。

"offset"パラメータを削除し、制限を1000に変更すると、実際にすべてのデータが一度に取得され、ページネーションを完全に削除できます。

希望に役立ちます!

EDIT:ロードしているページは常に同じです(最初のエントリセット、AAPLで始まります)。そして、上記のリソースからJavascriptによってデータがロードされます。 Javascriptは、掻き取っていたHTMLの内容を置き換えます。あなたのスクリプトは元のHTMLを見ているので(しかし、内容を置き換えるJavascriptは実行しません)、あなたは同じテーブルを何度も何度も何度も繰り返し取得します。

関連する問題