【问题标题】:How do I extract data from unspaced strings?如何从无空格的字符串中提取数据?
【发布时间】:2016-10-30 23:43:36
【问题描述】:

我需要从已在 BeautifulSoup 中解析的四个字符串中提取数据。它们是:

Arkansas72.21:59 AM76.29:04 AM5.22977.37:59 AM

Ashley71.93:39 AM78.78:59 AM0.53678.78:59 AM

Bradley72.64:49 AM77.28:59 AM2.41877.28:49 AM

Chicot-40.19:04 AM-40.19:04 AM2.573-40.112:09 AM

例如,第一个字符串中的数据是 Arkansas、72.1、1:59 AM、76.2、9:04 AM、5.2、29、77.3 和 7:59 AM。有没有简单的方法可以做到这一点?

编辑:完整代码

import urllib2
from bs4 import BeautifulSoup
import time

def scraper():

    #Arkansas State Plant Board Weather Web data
    url1 = 'http://170.94.200.136/weather/Inversion.aspx'

    #opens  url and parses HTML into Unicode
    page1 = urllib2.urlopen(url1)
    soup1 = BeautifulSoup(page1, 'lxml')

    #print(soup.get_text()) gives a single Unicode string of relevant data in strings from the url
    #Without print(), returns everything in without proper spacing
    sp1 = soup1.get_text()

    #datasp1 is the chunk with the website data in it so the search for Arkansas doesn't return the header
    #everything else finds locations for Unicode strings for first four stations
    start1 = sp1.find('Today')
    end1 = sp1.find('new Sys.')
    datasp1 = sp1[start1:end1-10]

    startArkansas = datasp1.find('Arkansas')
    startAshley = datasp1.find('Ashley')
    dataArkansas = datasp1[startArkansas:startAshley-2]

    startBradley = datasp1.find('Bradley')
    dataAshley = datasp1[startAshley:startBradley-2]

    startChicot = datasp1.find('Chicot')
    dataBradley = datasp1[startBradley:startChicot-2]

    startCleveland = datasp1.find('Cleveland')
    dataChicot = datasp1[startChicot:startCleveland-2]


    print(dataArkansas)
    print(dataAshley)
    print(dataBradley)
    print(dataChicot)

【问题讨论】:

  • 您能否也显示BeautifulSoup 特定部分?我怀疑问题可能在于您如何从 HTML 中提取这些数据。
  • 正则表达式可以做
  • @Copperfield:确实,正则表达式符合要求。但我认为 alecxe 认为这是 XY problem 是正确的。
  • 这完全取决于值的一致性。它们是否总是相同的,否则将很难确定第一行中的5.22977.3 之类的内容。可能是:5.22 97 7.35.2 29 77.3 有时也会发生同样的情况。是-40.11 2:09AM 还是-40.1 12:09AM,除非对数据有明确的规则,否则您将无法正确解析数据。
  • 170.94.200.136/weather/Inversion.aspx温度数据始终保留一位小数,但时间和倒数第三个值可以是多个字符/

标签: python beautifulsoup urllib2 bs4


【解决方案1】:

只需改进提取表格数据的方式即可。我会使用 pandas.read_html() 将其读入 dataframe,我敢肯定,您会发现使用起来很方便:

import pandas as pd

df = pd.read_html("http://170.94.200.136/weather/Inversion.aspx", attrs={"id": "MainContent_GridView1"})[0]
print(df)

【讨论】:

  • 我如何将每个表值作为自变量?
  • @MichaelFisher 是的,如果您之前没有使用过 pandas,请花一些时间研究如何使用它。这是值得的。您可以通过多种不同方式对其进行迭代,例如:stackoverflow.com/questions/16476924/…
  • 这比我以前做的要容易 100 倍。我会更多地研究熊猫。我是 Python 新手。
  • 还有一件事:由于所有行和列都从 0 开始,因此尝试获取每个值会导致将整个列从站拉到最高时间。有没有办法防止或解决这个问题?
  • 如果使用 pandas 你可以df = pd.read_html("http://170.94.200.136/weather/Inversion.aspx", attrs={"id": "MainContent_GridView1"})[0]
【解决方案2】:

你需要使用beautifulsoup来解析html页面并取回你的数据:

url1 = 'http://170.94.200.136/weather/Inversion.aspx'

#opens  url and parses HTML into Unicode
page1 = urlopen(url1)
soup1 = BeautifulSoup(page1)

# get the table
table = soup1.find(id='MainContent_GridView1')

# find the headers
headers = [h.get_text() for h in table.find_all('th')]

# retrieve data
data = {}
tr_elems = table.find_all('tr')
for tr in tr_elems:
    tr_content = [td.get_text() for td in tr.find_all('td')]
    if tr_content:
        data[tr_content[0]] = dict(zip(headers[1:], tr_content[1:]))

print(data)

这个例子将显示:

{
  "Greene West": {
    "Low Temp  (\u00b0F)": "67.7",
    "Time Of High": "10:19 AM",
    "Wind Speed (MPH)": "0.6",
    "High Temp  (\u00b0F)": "83.2",
    "Wind Dir (\u00b0)": "20",
    "Time Of Low": "6:04 AM",
    "Current Time": "10:19 AM",
    "Current Temp  (\u00b0F)": "83.2"
  },
  "Cleveland": {
    "Low Temp  (\u00b0F)": "70.8",
    "Time Of High": "10:14 AM",
    "Wind Speed (MPH)": "1.9",
    [.....]

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-10
    • 2019-08-03
    • 1970-01-01
    • 2017-04-07
    • 2023-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多