从网页数据表中获取数字

时间:2013-09-07 20:11:17

标签: python web-scraping

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

我正在尝试几种方式:

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

我能做什么:

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

我无法做到的事情:

对于更复杂的网页 like this,我无法做到这一点。我通过urllib2抓取的这个页面的HTML代码不包含我正在寻找的关键字和数据(如Flexural strength,弹性模量)? 实际上它似乎根本不包含wikipage!这怎么可能?这些wiki表是否以某种方式动态链接?如何通过urllib获得对表的争议?为什么urllib2没有抓取这些数据,而我的网络浏览器呢?

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

2 个答案:

答案 0 :(得分:1)

网络抓取很困难。不是因为它是火箭科学,而是因为它只是凌乱。目前,您需要为不同的地点手工制作刮刀并使用它们,只要该地点的结构不会改变。

网络信息提取有更多自动化方法,例如就像它在本文中描述的那样: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

答案 1 :(得分:1)

我不明白你的意思

  

它似乎根本不包含wikipage

我相对迅速地得到了这个:

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', '-']