2017-07-30 70 views
1

編輯:已解決。想我會在底部添加我的答案...用美麗的湯解析XML

注:所需的輸出是一樣

US D0591026 

我有數據,看起來像在XML下面一幫行:

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE us-patent-grant SYSTEM "us-patent-grant-v42-2006-08-23.dtd" [ ]> 
<us-patent-grant lang="EN" dtd-version="v4.2 2006-08-23" file="USD0591026-20090428.XML" status="PRODUCTION" id="us-patent-grant" country="US" date-produced="20090414" date-publ="20090428"> 
<us-bibliographic-data-grant> 
<publication-reference> 
<document-id> 
<country>US</country> 
<doc-number>D0591026</doc-number> 
<kind>S1</kind> 
<date>20090428</date> 
</document-id> 
</publication-reference> 
<application-reference appl-type="design"> 
<document-id> 
<country>US</country> 
<doc-number>29303426</doc-number> 
<date>20080208</date> 
</document-id> 
</application-reference> 
<us-application-series-code>29</us-application-series-code> 
<priority-claims> 
<priority-claim sequence="01" kind="national"> 
<country>CA</country> 
<doc-number>122078</doc-number> 
<date>20070830</date> 
</priority-claim> 
</priority-claims> 
<us-term-of-grant> 
<length-of-grant>14</length-of-grant> 
</us-term-of-grant> 
<classification-locarno> 
<edition>9</edition> 
<main-classification>0101</main-classification> 
</classification-locarno> 
<classification-national> 
<country>US</country> 
<main-classification>D 1106</main-classification> 
</classification-national> 
<invention-title id="d0e71">Edible fruit product in the shape of a rocketship</invention-title> 
<references-cited> 

我想拉出國家和文件號碼。我已經得到了這一點:

import os 
import io 
from bs4 import BeautifulSoup 
import csv 
import requests 

directory_in_str = 'C:/Users/somedirectory' 
directory = os.fsencode(directory_in_str) 

for file in os.listdir(directory): 
    filename = os.fsdecode(file) 
    full_name = directory_in_str + filename 
    handler = open(full_name).read() 
    soup = BeautifulSoup(handler, 'lxml') 
    patents=soup.find_all('us-patent-grant') 
    pub_ref=soup.find_all('publication-reference') 
    country=soup.find_all('country') 
    doc_num=soup.find_all('doc-number') 
    for patent in pub_ref: 
     for doc_num in patent: 
      print(doc_num) 

    continue 

我在哪裏可以打印出一個不錯的塊,其中包括這些元素(什麼上面的代碼一樣),但一切我試圖讓在這兩個特定元素(然後連接它們)失敗了。我已經能夠使用字符串操作,但數據集的格式不夠好(我將在沒有標準長度的情況下拔出文本字段)以確信我可以基於拼接字符串執行整個分析。

任何想法如何深入到那些更深層次的標籤並返回這兩個元素?

好了,我已經做了一些修改,並得到我的代碼:

import os 
import io 
from bs4 import BeautifulSoup 
import csv 
import requests 

directory_in_str = 'C:/somedir' 

directory = os.fsencode(directory_in_str) 

for file in os.listdir(directory): 
    filename = os.fsdecode(file) 
    full_name = directory_in_str + filename 
    handler = open(full_name).read() 
    soup = BeautifulSoup(handler, 'lxml') 
    patents=soup.find_all('us-patent-grant') 
    pub_ref=soup.find_all('publication-reference') 
    for patent in pub_ref: 
    country = patent.find_all('country') 
    doc_num = patent.find_all('doc-number') 
    print(country + doc_num) 

    continue 

這給了我的我想要什麼。我得到這個:

[<country>US</country>, <doc-number>D0591026</doc-number>] 

,但我想要的只是:

US D0591026 

我理解對象的類型是BS4結果集,但我不熟悉不夠用怎麼樣,我只回標籤中的東西。最終,這是一個csv,所以我不想在那裏有這些標籤。

我轉換的湯對象的字符串和使用正則表達式來獲得所需的輸出

... 
import re 
... 
... 
    country = patent.find_all('country') 
    doc_num = patent.find_all('doc-number') 
    country_str = str(country) 
    doc_num_str = str(doc_num) 
    country_str2 = re.search('>(.*)<', country_str) 
    doc_num_str2 = re.search('>(.*)<', doc_num_str) 
    print(country_str2.group(1) + doc_num_str2.group(1)) 
+0

你看着XPath或使用'etree'模塊呢? Beautfulsoup主要用於HTML,根據我的經驗 –

+0

我不明白你想要的輸出,它是一個列表,其中的元素是與doc號碼列表,它是相關的國家? –

+1

[編輯]你的問題,並顯示你想要的輸出。 – stovfl

回答

0

試試這個:

doc_nums=soup.find_all('doc-number') 
for num in doc_nums: 
    print(num.text) 
0

爲了得到一個清單,doc-number和它的使用列表理解相關countryzip,一個簡單的單行程將是:

>>> [(country.text,number.text) for country, number in zip(soup.findAll("country"), soup.findAll("doc-number"))] 
[('US', 'D0591026'), ('US', '29303426'), ('CA', '122078')] 

或許,如果你不習慣列表理解更可讀的方式:

>>> lst = [] 
>>> for country, number in zip(soup.findAll("country"), soup.findAll("doc-number")): 
    print(country.text, number.text) 
    lst.append((country.text, number.text)) 


US D0591026 
US 29303426 
CA 122078 
>>> lst 
[('US', 'D0591026'), ('US', '29303426'), ('CA', '122078')]