2017-11-14 6 views
0

私の仕事は、私のPythonスキルがはるかに短いと思います。私はオープンデータのウェブサイトから石油生産データを抜き出し、これをjson形式に変換しようとしています。私は、ヘッダと行データのリストを作成し、HTMLテーブルタグを介して実行しているいくつかの助けを借りて、現在ではJSONへのWebスクレイピングテーブル

。私が苦労しているのは、このデータの一部を1つのjsonレコード内にネストすることです。

今、私はすべて行またはヘッダごとにjsonを持っています。私はそれの下にヘッダーとすべての列データを持っています、そして、次のヘッダー(次のように)に行くそのデータの次のヘッダー。 Iは、ヘッダと一つのレコードとしてそれに割り当てられた行データのいずれかを持ちたい可能であれば

、次のヘッダと行3と次のJSONレコードに再びが、行2のデータと、その後のヘッダーを持っているでしょう。 テーブルソースを見れば他のオプションも意味があります。油田あたりの記録を持つことになりますが、このフィールドには年/月の生産値が異なる複数の行があります。

可能であれば、私はjsonフィールドレコードのすべてを取り込みたいと思います。 jsonレコード内には、1つのjsonレコードにキャプチャされた、複数の年/月の行が存在するはずです。

基本的にそれは私がちょうど私のpython能力の外にわずかで達成可能だと思う明確なHTMLテーブルのセル、上のpythonの残りの部分といくつかのループを使用するために必要だと思います。これは理にかなっているように思えます。

レコード(年:連結月フィールド)あたりの希望
[ 
"\u00c5SGARD", 
"2017", 
"8", 
"0.19441", 
"0.81545", 
"0.26954", 
"0.00000", 
"1.27940", 
"0.07432", 
"43765" 
] 

毎のヘッダ(これらのフィールドの下に、すべてのデータ列)

[ 
"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" 
] 

によるJSON

{ 
" 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スクリプト

HTMLを見ずに
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) 

答えて

0

伝えるのは難しいですが、私はあなたのテーブルが良く、このように行われることになるの解析推測しています:python BeautifulSoup parsing table。そうすれば、ヘッダーと値が一致することを確認できます。

私は答えを与えるためにあなたの教育への害になると思います。 (!行):だから私は、次のことができます願ってい

我々は項目のリストを持っている場合[ ('a', 1), {'a', 2), ('a', 3), ('b', 1), ('b', 2), ('b', 3)]と我々は、我々はただの辞書を追加することができ[ ('a': [1, 2, 3]), ('b': [1, 2, 3]) ]

のリストにそれらを有効にする

d = {} 
for v1, v2 in items: 
    d.setdefault(v1, []).append(v2) 

setdefaultここでは、私たちのリストのためにデフォルトでリストを持つためのショートカットです。このd.items()

は値を持つことになります。次のステップは、ヘッダーを組み込むことです。おそらく最初に一つの列Oil – saleableから始めてそこから構築してください。

+0

助けてくれてありがとう、私はそれが自分自身を働かせる方法を理解したいので、私は援助に感謝します。あとで少し勉強して、いくつかのBS辞書を実装できるかどうか確認します。 – Chris

+0

助けがあれば、ここで質問を明確にするよう依頼してください:) – typingduck

+0

は少し入れ子になった辞書を理解していますが、次のような本質的な行を、各行に対してループし、 '' yearmonth ''に基づいて '' fieldname''レコードごとに複数の行をネストするように内部的にループする必要があります。 [code](https://pyfiddle.io/fiddle/909beab3-d34a-4099-b8fc-04eaecfcd85b/?i=true) – Chris

関連する問題