我正在尝试为http://www.virginiaequestrian.com/main.cfm?action=greenpages&GPType=8抓取所有表值并将值放在列表列表中。出于某种原因,我似乎无法理解。将信息字典附加到数据列表只会将一个值放入364次(表的长度)。我在循环中单独打印每一行和值,我知道我正在抓取正确的元素/值,但是当我尝试将值放入数据列表时,一切似乎都会崩溃。
当我做错时,有人可以告诉我吗?
from bs4 import BeautifulSoup
import requests
r=requests.get('http://www.virginiaequestrian.com/main.cfm?action=greenpages&GPType=8')
soup=BeautifulSoup(r.content,'html5lib')
data = []
info = {}
tbl = soup.findAll('table')[2]
for tr in tbl.findAll('tr')[3:]:
for td in tr.findAll('td')[0]:
value= td.string
info['Name']=value
for td in tr.findAll('td')[1]:
value= td.string
info['City']=value
for td in tr.findAll('td')[2]:
value= td.string
info['Phone']=value
for td in tr.findAll('td')[3]:
value = "http://www.virginiaequestrian.com/{}".format(td.a['href'])
info['ListURL']=value
data.append(info)
print data
答案 0 :(得分:2)
python中的对象(如您的info
dict)使用对其基础数据结构的引用。在调用data.append(info)
时你基本上做的是一遍又一遍地对同一个词典添加相同的引用。
你可以做的是(重新)在最外面的for循环的每次迭代中创建你的info
dict:
for tr in tbl.findAll('tr')[3:]:
info = {}
...
或将您的词典副本附加到您的列表中:
data.append(info.copy())
每次都创建一个新对象。
您还可以简化内部for循环,因为不一定需要迭代一个值:
for td in tr.findAll('td')[0]:
value= td.string
info['Name']=value
for td in tr.findAll('td')[1]:
value= td.string
info['City']=value
for td in tr.findAll('td')[2]:
value= td.string
info['Phone']=value
for td in tr.findAll('td')[3]:
value = "http://www.virginiaequestrian.com/{}".format(td.a['href'])
info['ListURL']=value
可以成为
name, city, phone, url = tr.findAll('td')[:4]
info['Name'] = name.string
info['City'] = city.string
info['Phone'] = phone.string
info['ListURL'] = "http://www.virginiaequestrian.com/{}".format(url.a['href'])