【问题标题】:BeautifulSoup Iteration not workingBeautifulSoup 迭代不起作用
【发布时间】:2015-07-18 20:37:36
【问题描述】:
from bs4 import BeautifulSoup
import requests
s=requests.Session()
r=s.get('http://www.virginiaequestrian.com/main.cfm?action=greenpages&GPType=8')
soup=BeautifulSoup(r.text,'html5lib')

DataGrid=soup.find('tbody')
test=[]
for tr in DataGrid.find_all('tr')[:3]:
        for td in tr.find_all('td'):
            print td.string

您好,我正在尝试解析该网站的 html (http://www.virginiaequestrian.com/main.cfm?action=greenpages&GPType=8) 并获取表格数据。我试图从结果中排除前三个表行,但由于某种原因,我无法让解析器执行此操作。这是我的第一次专业抓取尝试,我完全不知道如何让它工作。我猜这可能与我正在使用的 html5lib 解析器有关,但老实说我不知道​​。有人可以告诉我如何让这个工作吗?

作为一个很好的测试,提取前三行数据非常有用。这样我可以确信完成的查询将从这些之外的任何内容中提取。

例如,表格中的第一行将是“Equestrian Web Sites”

【问题讨论】:

  • 添加你认为的前三行

标签: python parsing beautifulsoup


【解决方案1】:

你只取前三个而不忽略[:3],它从列表中切出前三个元素

 DataGrid.find_all('tr')[:3] # first three elements

应该是DataGrid.find_all('tr')[3:] # 除了前三个元素之外的所有元素

from bs4 import BeautifulSoup
import requests

r=requests.get('http://www.virginiaequestrian.com/main.cfm?action=greenpages&GPType=8')
soup=BeautifulSoup(r.content)

tbl = soup.find("table")
for tag in tbl.find_all("tr")[3:]:
    for td in tag.find_all('td'):
        print td.text

上述tbl.find_all("tr") 切片并使用两个不同的解析器输出时:

In [20]: soup=BeautifulSoup(r.content,"html.parser")

In [21]: tbl = soup.find("table")

In [22]: len(tbl.find_all("tr"))
Out[22]: 364

In [23]: len(tbl.find_all("tr")[3:])
Out[23]: 361

In [24]: soup=BeautifulSoup(r.content,"lxml")

In [25]: tbl = soup.find("table")

In [26]: len(tbl.find_all("tr")[3:])
Out[26]: 361

In [27]: len(tbl.find_all("tr"))
Out[27]: 364

如果你真的想要more hrefs,那么你应该这样做,为每个tr 获取a 标签,在你真正想要的行之前还有6个tr,所以你需要跳过6:

tbl = soup.find("table")
out = (tag.find('a') for tag in tbl.find_all("tr")[6:])

for a in out:
    print(a["href"])

输出:

main.cfm?action=greenpages&sub=view&ID=9068
main.cfm?action=greenpages&sub=view&ID=9504
main.cfm?action=greenpages&sub=view&ID=10868
main.cfm?action=greenpages&sub=view&ID=10261
main.cfm?action=greenpages&sub=view&ID=10477
main.cfm?action=greenpages&sub=view&ID=10708
main.cfm?action=greenpages&sub=view&ID=11712
main.cfm?action=greenpages&sub=view&ID=12402
main.cfm?action=greenpages&sub=view&ID=12496
..................

要使用链接,只需在主网址前添加:

for a in out:
    print("http://www.virginiaequestrian.com/{}".format(a["href"]))

输出:

http://www.virginiaequestrian.com/main.cfm?action=greenpages&sub=view&ID=9068
http://www.virginiaequestrian.com/main.cfm?action=greenpages&sub=view&ID=9504
http://www.virginiaequestrian.com/main.cfm?action=greenpages&sub=view&ID=10868
http://www.virginiaequestrian.com/main.cfm?action=greenpages&sub=view&ID=10261
http://www.virginiaequestrian.com/main.cfm?action=greenpages&sub=view&ID=10477
http://www.virginiaequestrian.com/main.cfm?action=greenpages&sub=view&ID=10708
http://www.virginiaequestrian.com/main.cfm?action=greenpages&sub=view&ID=11712
http://www.virginiaequestrian.com/main.cfm?action=greenpages&sub=view&ID=12402
http://www.virginiaequestrian.com/main.cfm?action=greenpages&sub=view&ID=12496
http://www.virginiaequestrian.com/main.cfm?action=greenpages&sub=view&ID=12633
http://www.virginiaequestrian.com/main.cfm?action=greenpages&sub=view&ID=13528

如果您打开第一个将引导您到马术网站,即您想要的第一个数据。

【讨论】:

  • 是的,我这样做是因为表格中有很多元素,我想测试切片是否正常工作。我改变了一堆数字,但我认为它没有任何效果。我总是拿回完整的清单....
  • 它对我有用,请尝试更改您的解析器,您确定打印DataGrid.find_all('tr')[:3]DataGrid.find_all('tr') 会得到完全相同的输出吗?
  • 如果我使用默认值或“lxml”,我会收到 NoneType 错误。这就是为什么我必须使用 html5lib。我打印 DataGrid=soup.find('tbody') test=[] for tr in DataGrid.find_all('tr'): for td in tr.find_all('td'): print td.text test.append(td) print '\n%i' % len(test) and include [:3] 我得到的计数是 3601。如果我不包括切片器,我得到的计数是 5399 ......实际上现在提出了一个问题为什么使用 364 个元素的表,前 3 个元素占总数的一半以上.....
  • 完全按照上面的方式运行代码,加上tbl.find_all("tr")[3:]tbl.find_all("tr")的长度
  • 别担心,如果我知道你只是想要更多的链接,生活会更简单!我添加了获取它们的代码
猜你喜欢
  • 2020-11-23
  • 2014-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多