首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将Web抓取表转换为JSON

将Web抓取表转换为JSON
EN

Stack Overflow用户
提问于 2017-11-15 03:12:57
回答 1查看 1.5K关注 0票数 0

我有一项任务,我认为我的python技能远远不够。我有一个石油生产数据从一个开放的数据网站抓取,并希望将其转换为json格式。

目前,在一些帮助下,我已经运行了html表标记来构建标题和行数据的列表。我正在努力的是将其中的一些数据嵌套在一个json记录中。

现在,我要么按行获得所有的json,要么按标头列出。我有一个标题和它下面的所有列数据,然后下一个标题及其数据进入下一个标题(如下所示)。

如果可能,我希望将标题和行数据分配给它作为一条记录,下一条记录将再次具有标题,但具有第2行数据,然后使用标题和第3行到下一条json记录。如果查看表源…,则另一个选项将是有意义的。可能是每个油田都有一个记录,这个油田可能有多个行,对应于不同的年/月生产值。

如果可能的话,我想在json字段记录中捕获所有这些信息。在json记录中,它将在一个json记录中捕获多个年/月行(如果它们存在)。

从本质上说,它认为需要在不同的html表格单元格上使用几个循环,我认为这是可以实现的,只是稍微超出了我的python能力。希望这是有意义的,试图相当描述性的。

JSON by Row

代码语言:javascript
复制
[
"\u00c5SGARD",
"2017",
"8",
"0.19441",
"0.81545",
"0.26954",
"0.00000",
"1.27940",
"0.07432",
"43765"
]

每个标题(这些字段下的每个数据列)

代码语言:javascript
复制
[
"Field (Discovery)":[cell1,cell2,cell3,cell4 etc]
"Year":[cell1,cell2,cell3,cell4 etc],
"Month":[cell1,cell2,cell3,cell4 etc],
"Oil - saleable div[mill Sm3]":[cell1,cell2,cell3,cell4 etc],
"Gas - saleable div[bill Sm3]":[cell1,cell2,cell3,cell4 etc],
"NGL - saleable div[mill Sm3]",
"Condensate - saleable div[mill Sm3]",
"Oil equivalents - saleable div[mill Sm3]",
"Water - wellbores div[mill Sm3]",
"NPDID information carrier"
]

每条记录所需的值(连接的年份:月份字段)

代码语言:javascript
复制
{
 " Field (Discovery)":"asset1" ,
 " Oil – saleable":
  [
   { "yearmonth":"201701","unit":"mmboe","value":"1234.456"},                    
   { "yearmonth ":"201702","unit":"mmboe","value":"124.46"}],
 "Gas - saleable":              
  [
    {"yearmonth":"201701","unit":" bill Sm3","value":"1234.456"},
    {" yearmonth ":"201702","unit":"mill Sm3","value":"14.456"}],
 "NGL - saleable ":
  [
   {"yearmonth":"201704","unit":"mill Sm3","value":"1.456"}, 
   {" yearmonth ":"201706","unit":" bill Sm3","value":"14.456"}], 
 "Condensate – saleable":
  [
   {"yearmonth":"201701","unit":" mill Sm3","value":"23.60"},
   {"yearmonth ":"201608","unit":"mill Sm3","value":"4.4"}],
  "NPDID information carrier":"43765"
}

当前python脚本

代码语言:javascript
复制
import requests
from bs4 import BeautifulSoup
import json
import boto3
import botocore
from datetime import datetime
from collections import OrderedDict

starttime = datetime.now()

#Agent detail to prevent scraping bot detection
user_agent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) 
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.47 
Safari/537.36'

header = {'User-Agent' : user_agent }

# Webpage connection
html = "http://factpages.npd.no/ReportServer?/FactPages/TableView/
field_production_monthly&rs:Command=Render&rc:Toolbar=false
&rc:Parameters=f&Top100=True&IpAddress=108.171.128.174&CultureCode=en"

r=requests.get(html, headers=header)
c=r.content
soup=BeautifulSoup(c,"html.parser")


rows = soup.findAll('td', {
'class': ['a61cl', 'a65cr', 'a69cr', 'a73cr', 'a77cr', 'a81cr', 
'a85cr','a89cr', 'a93c', 'a97cr']})

headers = soup.findAll('td', {
'class': ['a20c', 'a24c', 'a28c', 'a32c', 'a36c', 'a40c', 'a44c', 
'a48c','a52c', 'a56c']})

headers_list = [item.getText('div') for item in headers]

rows_list=[item.getText('div') for item in rows]

final=[rows_list[item:item+10] for item in range(0,len(rows_list),10)]

row_header={}
 for item in final:
  for indices in range(0,10):
    if headers_list[indices] not in row_header:
        row_header[headers_list[indices]]=[item[indices]]
      else:
        row_header[headers_list[indices]].append(item[indices])


#OrderedDict
result= (json.dumps(row_header, indent=4, sort_keys=True, 
ensure_ascii=False))
 with open('data.txt', 'wt') as outfile:

#json dump print
json.dump(result, outfile,indent=4, sort_keys=True,
separators=(',', ': '), ensure_ascii=False)


#Time
runtime = datetime.now() - starttime
print(runtime)
EN

回答 1

Stack Overflow用户

发布于 2017-11-15 04:01:56

看不到HTML很难判断,但我猜解析您的表会更好,就像这样:python BeautifulSoup parsing table。这样,您就可以确保标题和值匹配。

我认为给出答案对你的教育是有害的。因此,我希望以下内容能有所帮助:

如果我们有一个项目列表( [ ( 'a': [1, 2, 3] ), ('b': [1, 2, 3] ) ]!),我们想把它们转换成一个行的列表,那么就需要使用[ ('a', 1 ), {'a', 2), ('a', 3), ('b', 1), ('b', 2), ('b', 3)]

然后我们就可以添加一个字典

代码语言:javascript
复制
d = {}
for v1, v2 in items:
  d.setdefault(v1, []).append(v2)

这里的setdefault只是一个在默认情况下拥有列表的快捷方式。

在此之后,d.items()将具有这些值。然后,下一步将是合并头部。也许一开始只从一列Oil – saleable开始,然后从那里开始构建。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47293558

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档