我正在尝试使用Beautiful Soup和Python收集网址列表。我是两者的新用户,我需要帮助找出如何使用通配符查找href值。 HTML代码看起来像
<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]
从以前编译的url列表中提取变量teams_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&#39;每个团队列表中的变量。
问题2)数据中有50年(行),但我只想将标签从2012年拉到2000年。我该怎么做?
此外,由于html代码中的行标记为<tr class data-row="0">
,因此我的代码中可能会出现拼写错误,但是,由于某种原因,lxml和html5解析器都返回了标记的属性作为<tr class="">
并且我不知道为什么或如何解决这个问题,所以任何额外的帮助都会很棒。
谢谢
答案 0 :(得分:1)
几点:
此:
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的元素发生属性错误...
然后在完成所有工作后,你应该能够继续......
答案 1 :(得分:0)
您可以在find_all
:
>>> 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>
标记之间的文字。