用美丽的汤解析XML

时间:2017-07-30 02:31:59

标签: python xml beautifulsoup

编辑:已解决。以为我在底部添加了答案......

注意:所需的输出是一堆像

这样的行
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))

2 个答案:

答案 0 :(得分:1)

要使用列表推导和doc-number获取包含country及其相关zip的列表,一个简单的单行将是:

>>> [(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')]

答案 1 :(得分:0)

试试这个:

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