【发布时间】:2014-05-02 04:03:27
【问题描述】:
我正在尝试学习一些基本的网络抓取。我最初设置了scrapy,并注意到它有点令人生畏,所以我决定在开始爬行之前先使用beautifulsoup 进行一些单页抓取练习。我的项目想法是抓取下表并将信息输出到excel文件。
该表位于维基百科的此页面: http://en.wikipedia.org/wiki/List_of_largest_corporate_profits_and_losses
我得到的输出相当成功!但是,我不确定我的代码是否非常“pythonic”。我有点粗暴地强迫我使用一些正则表达式来抓取数据,我觉得肯定有一种更简单、更快捷的方法来抓取表格数据并删除一些讨厌的 u'Name' 格式和图像链接,这些链接放置在整个桌子。将来,我想知道除了我的hacky方式之外,刮桌子和删除格式的标准方法是什么。
具体来说,在表格的第 3 列中,我们看到有一个国家国旗的图像以及我关心的信息(国家名称)。因此,我不能只做单元格[3 ].find(文本=真)。我通过仅抓取单元格 3 中的所有 a 标签,然后使用正则表达式仅抓取标题中包含的国家/地区名称来解决此问题:
for j,cell in enumerate(cells):
if j%3 == 0:
text = (cell.findAll('a'))
感谢和抱歉这么长的帖子!
from bs4 import BeautifulSoup
import urllib2
import re
wiki = "http://en.wikipedia.org/wiki/List_of_largest_corporate_profits_and_losses"
header = {'User-Agent': 'Mozilla/5.0'} #Needed to prevent 403 error on Wikipedia
req = urllib2.Request(wiki,headers=header)
page = urllib2.urlopen(req)
soup = BeautifulSoup(page)
table = soup.find("table", { "class" : "wikitable sortable" })
f = open('output.csv', 'w')
num = []; company = []; industry = []; country = []; year = []; reportdate = [];
earnings = []; usdinflation = []; usdrealearnings = []; cunts = [];
for i,row in enumerate(table.findAll("tr")):
cells = row.findAll("td")
if len(cells) == 9:
num.append(cells[0].find(text=True))
company.append(cells[1].findAll(text=True))
industry.append(cells[2].find(text=True))
country.append(cells[3].find(text=True))
year.append(cells[4].find(text=True))
reportdate.append(cells[5].find(text=True))
earnings.append(cells[6].find(text=True))
usdinflation.append(cells[7].find(text=True))
usdrealearnings.append(cells[8].find(text=True))
for j,cell in enumerate(cells):
if j%3 == 0:
text = (cell.findAll('a'))
newstring = re.search(r'(title="\w+\s\w+")|(title="\w+")',str(text))
if not(newstring is None):
newstring2 = re.search(r'("\w+")|("\w+\s\w+")',newstring.group())
cunts.append(newstring2.group())
for i in range(len(num)):
s = str(company[i])
newstring = re.search(r'\w+\s|\w+\w+', s).group();
write_to_file = str(num[i])+ "," + newstring + "," + str(industry[i]) + "," + cunts[i].encode('utf-8') + ","+ str(year[i]) + ","+ str(reportdate[i])+ ","+ earnings[i].encode('utf-8') + "," + str(usdinflation[i]) + "," + str(usdrealearnings[i]) + "\n";
f.write(write_to_file)
f.close()
【问题讨论】:
-
是的,您可以进行一些更改来清理它。对于初学者,一旦您定义了“表”,您可以使用 print table.prettify() 打印出该数据以查看表节点的子父关系,这使得在编码每个步骤时更容易知道导航到什么。我会尽快发布完整的答案并提出一些建议
标签: python web-scraping beautifulsoup wikipedia