【发布时间】:2017-05-05 09:30:52
【问题描述】:
此代码旨在遍历所有结果页面,然后遍历每个页面上的结果表,并从表中抓取所有数据以及存储在表外的一些信息。
但是,生成的 CSV 文件似乎没有任何合理的组织,每一行在不同的列中都有不同类别的信息。 What I am after is for each row to contain all the categories of information defined (date, party, start date, end date, electoral district, registered association, whether or not the candidate was elected, name of candidate, address, and financial agent )。其中一些数据存储在每页的表格中,而其余数据(日期、政党、地区、注册协会)存储在表格之外,需要与每页上每个表格行中的每个候选人相关联。 Additionally, there does not seem to be any output for 'elected', 'address', or 'financial agent,' and I am not sure where I am going wrong.
如果您能帮助我弄清楚如何修复我的代码以实现此输出,我将不胜感激。如下:
from bs4 import BeautifulSoup
import requests
import re
import csv
url = "http://www.elections.ca/WPAPPS/WPR/EN/NC?province=-1&distyear=2013&district=-1&party=-1&pageno={}&totalpages=55&totalcount=1368&secondaryaction=prev25"
rows = []
for i in range(1, 56):
print(i)
r = requests.get(url.format(i))
data = r.text
soup = BeautifulSoup(data, "html.parser")
links = []
for link in soup.find_all('a', href=re.compile('selectedid=')):
links.append("http://www.elections.ca" + link.get('href'))
for link in links:
r = requests.get(link)
data = r.text
cat = BeautifulSoup(data, "html.parser")
header = cat.find_all('span')
tables = cat.find_all("table")[0].find_all("td")
rows.append({
#"date":
header[2].contents[0],
#"party":
re.sub("[\n\r/]", "", cat.find("legend").contents[2]).strip(),
#"start_date":
header[3].contents[0],
#"end_date":
header[5].contents[0],
#"electoral district":
re.sub("[\n\r/]", "", cat.find_all('div', class_="group")[2].contents[2]).strip(),
#"registered association":
re.sub("[\n\r/]", "", cat.find_all('div', class_="group")[2].contents[2]).strip().encode('latin-1'),
#"elected":
re.sub("[\n\r/]", "", cat.find_all("table")[0].find_all("td", headers="elected/1")[0].contents[0]).strip(),
#"name":
re.sub("[\n\r/]", "", cat.find_all("table")[0].find_all("td", headers="name/1")[0].contents[0]).strip(),
#"address":
re.sub("[\n\r/]", "", cat.find_all("table")[0].find_all("td", headers="address/1")[0].contents[0]).strip(),
#"financial_agent":
re.sub("[\n\r/]", "", cat.find_all("table")[0].find_all("td", headers="fa/1")[0].contents[0]).strip()
})
with open('scrapeOutput.csv', 'w') as f_output:
csv_output = csv.writer(f_output)
csv_output.writerows(rows)
【问题讨论】:
-
您要抓取所有条目吗?还是您想按搜索条件之一(省/地区、重新分配年份、选区、政党、协会关键字、参赛者关键字、比赛日期)进行过滤?
-
您使用哪个分隔符?另外,如果您在某些字段中有分隔符,您是否使用quotechar?
-
@IvanChaer 我想在没有任何过滤的情况下抓取所有内容,到目前为止,我的代码基本上可以做到这一点——这只是获取存储在每个页面上的所有信息的问题,加上 csv 输出问题。
-
我们不能直接从详情页刮下来吗(elections.ca/WPAPPS/WPR/EN/NC/…)?这样我们就可以避免从两个不同的 url 中抓取一个项目。
-
谢谢大家!输出表看起来很棒。我创建了第二个问题,关于如何重写我的代码,以便刮掉每个表中所有参赛者的姓名,而不仅仅是第一个。如果你有什么想法,那就here
标签: python html python-3.x csv web-scraping