0

我经常需要为一些技术计算设置物理属性。手工填写这样的数据是不方便的。我想使用 python 脚本从一些公共网页(例如维基百科)中获取这些数据。

我尝试了几种方法:

  • 使用像lxml.etree这样的html 解析器(我没有经验 - 我只是想按照教程)
  • 使用pandas wikitable 导入(--,,--)
  • 使用urllib2下载 html 源代码,然后通过正则表达式搜索关键字

我能做的:

我没有找到适用于各种信息来源的通用解决方案。我制作的唯一真正有效的脚本只使用了简单的 urllib2 和正则表达式。它可以从这个纯 HTML页面中获取元素的物理属性。

我不能做的事情:

对于像这样更复杂的网页,我无法做到这一点。我通过 urllib2 抓取的这个页面的 HTML 代码不包含我正在寻找的关键字和数据(如弯曲强度、弹性模量)?实际上,它似乎根本不包含维基页面!这怎么可能?这些 wiki 表格是否以某种方式动态链接?我怎样才能通过 urllib 竞争表?为什么 urllib2 不抓取这些数据,而我的网络浏览器却抓取了?

我没有网络编程经验。我不明白为什么从免费的公共在线信息源中获取任何机器可读的数据如此困难。

4

2 回答 2

1

网页抓取很困难。不是因为它是火箭科学,而是因为它只是一团糟。目前,您需要为不同的站点手工制作刮板,并在站点结构不变的情况下使用它们。

Web 信息提取有更多的自动化方法,例如在本文中描述的那样:Harvesting Relational Tables from Lists on the Web,但这还不是主流。

大量网页包含以“列表”形式结构化的数据。许多这样的列表可以进一步拆分为多列表然后可以用于更具语义意义的任务。但是,从此类列表中获取关系表可能是一项具有挑战性的任务。列表是手动生成的,因此不需要定义良好的模板——它们有不一致的分隔符(如果有的话)并且经常缺少信息。


但是,有很多工具可以更快地获取 (HTML) 内容,例如BeautifulSoup

Beautiful Soup 是一个 Python 库,专为屏幕抓取等快速周转项目而设计。

>>> from BeautifulSoup import BeautifulSoup as Soup
>>> import urllib
>>> page = urllib.urlopen("http://www.substech.com/dokuwiki/doku.php?"
               "id=thermoplastic_acrylonitrile-butadiene-styrene_abs").read()
>>> soup = Soup(page) # the HTML gets parsed here
>>> soup.findAll('table') 

示例输出:https ://friendpaste.com/DnWDviSiHIYQEBduTqkWd 。更多文档可以在这里找到:http ://www.crummy.com/software/BeautifulSoup/bs4/doc/#searching-the-tree 。

如果您想从更大的页面集提取数据,请查看scrapy

于 2013-09-07T20:26:01.667 回答
1

我不明白你的意思

它似乎根本不包含维基页面

我得到这个相对较快:

import httplib
import re

hostu = 'www.substech.com'
timeout = 7
hypr = httplib.HTTPConnection(host=hostu,timeout = timeout)

rekete_page = ('/dokuwiki/doku.php?id='
               'thermoplastic_acrylonitrile-butadiene-styrene_abs')

hypr.request('GET',rekete_page)
x = hypr.getresponse().read()
hypr.close()

#print '\n'.join('%d %r' % (i,line) for i,line in enumerate(x.splitlines(1)))

r = re.compile('\t<tr>\n.+?\t</tr>\n',re.DOTALL)

r2 = re.compile('<th[^>]*>(.*?)</th>')
r3 = re.compile('<td[^>]*>(.*?)</td>')

for y in r.findall(x):
    print
    #print repr(y)
    print map(str.strip,r2.findall(y))
    print map(str.strip,r3.findall(y))

结果

[]
['<strong>Thermoplastic</strong>']

[]
['<strong>Acrylonitrile</strong><strong>-Butadiene-Styrene (ABS)</strong>']

[]
['<strong>Property</strong>', '<strong>Value in metric unit</strong>', '<strong>Value in </strong><strong>US</strong><strong> unit</strong>']

['Density']
['1.05 *10\xc2\xb3', 'kg/m\xc2\xb3', '65.5', 'lb/ft\xc2\xb3']

['Modulus of elasticity']
['2.45', 'GPa', '350', 'ksi']

['Tensile strength']
['45', 'MPa', '6500', 'psi']

['Elongation']
['33', '%', '33', '%']

['Flexural strength']
['70', 'MPa', '10000', 'psi']

['Thermal expansion (20 \xc2\xbaC)']
['90*10<sup>-6</sup>', '\xc2\xbaC\xcb\x89\xc2\xb9', '50*10<sup>-6</sup>', 'in/(in* \xc2\xbaF)']

['Thermal conductivity']
['0.25', 'W/(m*K)', '1.73', 'BTU*in/(hr*ft\xc2\xb2*\xc2\xbaF)']

['Glass transition temperature']
['100', '\xc2\xbaC', '212', '\xc2\xbaF']

['Maximum work temperature']
['70', '\xc2\xbaC', '158', '\xc2\xbaF']

['Electric resistivity']
['10<sup>8</sup>', 'Ohm*m', '10<sup>10</sup>', 'Ohm*cm']

['Dielectric constant']
['2.4', '-', '2.4', '-']
于 2013-09-07T21:40:18.770 回答