【问题标题】:Issue extracing specific XML values via BS4 and write them into dataframe通过 BS4 提取特定 XML 值并将它们写入数据帧
【发布时间】:2021-03-25 02:48:26
【问题描述】:

我是 Python 新手,我正在尽最大努力抓取一些 XML 数据。 到目前为止,我使用findget 方法让它适用于“正常”xPaths 和属性,但我正在努力解决最后一点。

这是 XML 的一个示例部分:

<root>
<job>
<othernodes>text</othernodes>
<advertiser>INPUT I WANT
    <node2>text</node2>
    <node3>text</node3>
</advertiser>
<othernodes>text</othernodes>
</job>

这是我脚本的一部分:

from bs4 import BeautifulSoup
import pandas as pd
import requests

url = "sample url"

xml_data = requests.get(url).content
soup = BeautifulSoup(xml_data, "xml")

#Find the tag/child
child = soup.find("job")

Company = []

while True:
        try:
            Company.append(" ".join(child.find('advertiser')))
        except:
            Company.append(" ")
        try:
            # Next sibling of child, here: job
            child = child.find_next_sibling('job')
        except:
            break


data = []
data = pd.DataFrame({
    "advertiser":Company,
                        })

如果我打印结果,它不会为节点广告商返回任何值。 我尝试解决此问题,但找不到解决方案。 谢谢!

【问题讨论】:

  • 如果你使用 XPath 可能会更干净?

标签: python xml pandas beautifulsoup


【解决方案1】:

不用ElementTree,用BeautifulSoup就可以了。

尝试调用返回第一个匹配项的.find_next() 方法:

from bs4 import BeautifulSoup

xml = """<root>
<job>
<othernodes>text</othernodes>
<advertiser>INPUT I WANT
    <node2>text</node2>
    <node3>text</node3>
</advertiser>
<othernodes>text</othernodes>
</job>"""

soup = BeautifulSoup(xml, "html.parser")

print([soup.find("advertiser").find_next(text=True).strip()])

# Or using `find_all()`
# print([tag.find_next(text=True).strip() for tag in soup.find_all("advertiser")])

输出:

['INPUT I WANT']

【讨论】:

    【解决方案2】:

    下面是你需要的代码

    import xml.etree.ElementTree as ET
    
    XML = '''<root>
        <job>
        <othernodes>text</othernodes>
        <advertiser>add1
            <node2>text</node2>
            <node3>text</node3>
        </advertiser>
        <othernodes>text</othernodes>
        </job>
        <job>
        <othernodes>text</othernodes>
        <advertiser>add2
            <node2>text</node2>
            <node3>text</node3>
        </advertiser>
        <othernodes>text</othernodes>
        </job>
    </root>'''
    root = ET.fromstring(XML)
    data = [a.text.strip() for a in root.findall('.//advertiser')]
    print(data)
    

    输出

    ['add1', 'add2']
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-04-20
      • 2014-10-06
      • 2019-02-01
      • 1970-01-01
      • 2017-12-26
      • 2017-05-24
      • 2019-05-08
      • 1970-01-01
      相关资源
      最近更新 更多