2013-11-23 111 views
0

我想收集使用美麗的湯和Python的網址列表。我是兩個新用戶,我需要幫助瞭解如何使用通配符查找href值。 HTML代碼看起來像使用通配符查找href值Beautifulsoup

<table class="sortable stats_table" id="team_index"> 
<colgroup>...</colgroup> 
<thead>...</thead> 
<tbody> 
    <tr class data-row="0"> 
      <td align="left">...</td> 
      <td align="left">...</td> 
      <td align="left"> 
       <a href="/teams/crd/2013.htm">Arizona Cardinals</a> 
      </td> 
      <td align="right">6</td> 
    <tr class data-row="1"> 
      <td align="left">...</td> 
      <td align="left">...</td> 
      <td align="left"> 
       <a href="/teams/crd/2012.htm">Arizona Cardinals</a> 
      </td> 
      <td align="right">6</td> 
</tbody> 
<tfoot></tfoot> 
</table> 

爲了簡潔起見,我只包含了html表的前兩行。我想找到所有<a>標籤與href="/teams/XXX/YYYY.htm"其中XXX是團隊名稱和YYYY年,並把它們全部列入一個網址列表。現在我用下面的代碼

from bs4 import BeautifulSoup 
from urllib2 import urlopen  
import re 

BASE_URL = "http://www.pro-football-reference.com" 
teams_url = ("http://www.pro-football-reference.com/teams/crd/") 

soup=BeautifulSoup(urlopen(teams_url),"lxml") 

teamtable = soup.find(lambda tag: tag.name=="table" and tag.has_attr("id") and  
      tag["id"]=="team_index") 

rows = teamtable.find_all("tr", attrs={""}) 

test=rows.find_all('a', {'href': lambda x : x.startswith('/teams/')}) 

masterlist = [BASE_URL + link.a["href"] for link in test] 

其中變量teams_url正在從先前編譯URL列表拉帶形式"http://www.pro-football-reference.com/teams/XXX/"的成員。我提供的代碼提供了以下錯誤,由於最後一行:

Traceback (most recent call last): 
File "<stdin>", line 1, in <module> 
AttributeError: 'ResultSet' object has no attribute 'find_all' 
soup.find_all('a', {'href': lambda x : x.startswith('/teams/')}) 

問題1)我怎樣才能使代碼收集所有的標籤在表格中我有一個像

masterlist = [`www.pro-football-reference.com/teams/crd/2013', 
       `www.pro-football-reference.com/teams/crd/2012', 
       `www.pro-football-reference.com/teams/crd/2011' 
       ...] 
列表

沒有對團隊縮寫進行硬編碼,因爲我將從每個團隊的列表中爲該代碼傳遞一個`teams_url'變量。

問題2)數據中有50年(行),但我只想從2012年到2000年,包括2000年。我該怎麼做?

而且,它可能看起來像有在我的代碼輸入錯誤,因爲這些行HTML代碼標記<tr class data-row="0">,但是,由於某種原因,無論是LXML和HTML5分析器返回標籤的屬性作爲<tr class="">,我不知道爲什麼或如何解決這個問題,所以任何額外的幫助都會很棒。

謝謝

回答

0

您可以在find_all的ATTRIB匹配參數使用正則表達式:

>>> import re 
>>> for possible_link in soup.find_all('a', {'href': re.compile(r'/teams/crd/\d.*')}): 
... print possible_link.text, possible_link.attrs 
... 
2013 {'href': '/teams/crd/2013.htm'} 
Arizona Cardinals {'href': '/teams/crd/2013.htm'} 
2012 {'href': '/teams/crd/2012.htm'} 
Arizona Cardinals {'href': '/teams/crd/2012.htm'} 
-- SNIP -- 
1920 {'href': '/teams/crd/1920.htm'} 
Chicago Cardinals {'href': '/teams/crd/1920.htm'} 

總之,.attrs將包含你正在尋找的HREF和.text與展示你的文字介於<a>TEXT</a>標籤之間。

+0

感謝您的幫助。我打算將整個過程嵌套在一個循環中並遍歷團隊。如果我想離開團隊目錄文件夾通用,那麼在每次迭代時它只會找到所有具有屬性'href =「/ teams/xxx/yyyy.htm」''的'標籤,此外,只有2000 - 2012年? –

0

幾點:

此:

teamtable = soup.find(lambda tag: tag.name=="table" and tag.has_attr("id") and  
      tag["id"]=="team_index") 

可以簡單地:

teamtable = soup.find('table', {'id': 'team_index'}) 

下是沒有做什麼你覺得... attrs = {""}創建一組一項目(一個空字符串),而attrs需要映射:

rows = teamtable.find_all("tr", attrs={""}) 

您可以刪除attrs並改爲使用此rows = teamtable.find_all('tr')

然後:

test=rows.find_all('a', {'href': lambda x : x.startswith('/teams/')}) 

能成爲(有用的,如果您想以後做更復雜的匹配):

import re 
test = rows.find_all('a', href=re.compile('/teams/')) 

或者,至少lambda x: x and x.startswith('/teams/'),以避免在沒有元素屬性錯誤href ...

然後,所有的工作,你應該能夠進一步...