使用BeautifulSoup find方法从表行中获取数据

时间:2017-08-05 12:51:25

标签: python web-scraping beautifulsoup

我正在编写一个Python脚本,使用BeautifulSoup从这个网页中抓取值:https://uk-air.defra.gov.uk/latest/currentlevels

我想使用soup.find()从“监控站点”为“Edinburgh St Leonards”的表格行中获取“每小时平均二氧化氮”和“上次更新”的值。

由于我不熟悉网络抓取,我遇到了一些麻烦,所以对此有任何帮助都会感激不尽。

3 个答案:

答案 0 :(得分:2)

将所有html表废弃到表格列表中。 表索引可能会更改,那么您不应该依赖行/列索引。 下面脚本的一部分查找搜索数据的索引。此外,它打印标题名称:因此您知道想要的是您获得的数据。

from bs4 import BeautifulSoup
import urllib.request
import re

with urllib.request.urlopen('https://uk-air.defra.gov.uk/latest/currentlevels?view=region') as response:
   htmlData = response.read()
soup = BeautifulSoup(htmlData, 'html5lib')

tables = soup.find_all('table', attrs={'class':'current_levels_table'})

#what you want to check:
Iwant = ['nitrogen', 'update']
about = 'Edinburgh'
for table in tables:
    #get header to have the data (we're looking for) column number and table real names
    table_head = table.find('thead')
    headrows = table_head.find_all('tr')
    measures = headrows[1].find_all('th')
    for colnum, measure in enumerate(measures):
        index.update({colnum: measure.text.strip() for wanted in Iwant if re.search(wanted+'(?iu)', measure.text)})
    #get table content and look for Edinburgh
    table_body = table.find('tbody')
    rows = table_body.find_all('tr')
    for row in rows:
        cels = row.find_all('td')
        rowContent = [cel.text.strip().replace(u'\xa0', u' ').replace(u'\n        Timeseries Graph', u'') for cel in cels if cel]
        if re.search(about+'(?iu)', rowContent[0]):
            for indexwanted, measurewanted in index.items():
                print(measurewanted, ':', rowContent[indexwanted])

答案 1 :(得分:1)

利用d2718nis的建议,你可以这样做。当然,还有很多其他方法也可以。

首先,找到拥有爱丁堡St Leonards'的链接。其中的文字。然后找到该链接元素的 grand 父元素,它是tr元素。现在确定td中的tr元素。检查表时,您会看到所需的列是第4和第7列。将所有td元素中的元素作为(0-相对)第3和第6个元素。最后,显示这些元素的粗略文本。

您需要做一些聪明的事情,从这些结果中提取正确可读的字符串。

>>> import requests
>>> import bs4
>>> page = requests.get('https://uk-air.defra.gov.uk/latest/currentlevels', headers={'User-Agent': 'Not blank'}).content
>>> soup = bs4.BeautifulSoup(page, 'lxml')
>>> Edinburgh_link = soup.find_all('a',string='Edinburgh St Leonards')[0]
>>> Edinburgh_link 
<a href="../networks/site-info?site_id=ED3">Edinburgh St Leonards</a>
>>> Edinburgh_row = Edinburgh_link.findParent('td').findParent('tr')
>>> Edinburgh_columns = Edinburgh_row.findAll('td')
>>> Edinburgh_columns[3]
<td class="center"><span class="bg_low1 bold">20 (1 Low)</span></td>
>>> Edinburgh_columns[6]
<td>05/08/2017<br/>14:00:00</td>
>>> Edinburgh_columns[3].text
'20\xa0(1\xa0Low)'
>>> Edinburgh_columns[6].text
'05/08/201714:00:00'

答案 2 :(得分:0)

你可以从这开始:

import requests
from bs4 import BeautifulSoup


# Request the page, set headers to prevent 403 Forbidden
page = requests.get(
    url='https://uk-air.defra.gov.uk/latest/currentlevels',
    headers={'User-Agent': 'Not blank'})
# Get html from page
html = page.text
# BeautifulSoup object
soup = BeautifulSoup(html, 'html5lib')

for table in soup.find_all('table'):
    # Print all tables on the page
    print(table)