【问题标题】:Textual parsing文本解析
【发布时间】:2020-05-03 16:54:24
【问题描述】:

我是 Python 和 Panda 的新手,但我想从多个下载的文件(格式相同)中进行解析。 在每个 HTML 中,都有一个像下面这样提到高管的部分。

<DIV id=article_participants class="content_part hid">
<P>Redhill Biopharma Ltd. (NASDAQ:<A title="" href="http://seekingalpha.com/symbol/rdhl" symbolSlug="RDHL">RDHL</A>)</P>
<P>Q4 2014 <SPAN class=transcript-search-span style="BACKGROUND-COLOR: yellow">Earnings</SPAN> Conference <SPAN class=transcript-search-span style="BACKGROUND-COLOR: #f38686">Call</SPAN></P>
<P>February 26, 2015 9:00 AM ET</P>
<P><STRONG>Executives</STRONG></P>
<P>Dror Ben Asher - CEO</P>
<P>Ori Shilo - Deputy CEO, Finance and Operations</P>
<P>Guy Goldberg - Chief Business Officer</P>

在文件中还有一个名为“DIV id=article_qanda class="content_part hid”的部分,其中像 Ori Shilo 这样的高管被命名,后面跟着一个答案,比如:

<P><STRONG><SPAN class=answer>Ori Shilo</SPAN></STRONG></P>
<P>Good morning, Vernon. Both safety which is obvious and fertility analysis under the charter of the data and safety monitoring board will be - will be on up.</P>

到目前为止,我只成功地使用了一个 html 解析器,按姓名收集了一个人的所有答案。我不确定如何继续并将代码基于可变的高管列表。有人有什么建议吗?

import textwrap
import os
from bs4 import BeautifulSoup

directory ='C:/Research syntheses - Meta analysis/SeekingAlpha/out'
for filename in os.listdir(directory):
    if filename.endswith('.html'):
        fname = os.path.join(directory,filename)
        with open(fname, 'r') as f:
            soup = BeautifulSoup(f.read(),'html.parser')

print('{:<30} {:<70}'.format('Name', 'Answer'))
print('-' * 101)
for answer in soup.select('p:contains("Question-and-Answer Session") ~ strong:contains("Dror Ben Asher") + p'):
    txt = answer.get_text(strip=True)

    s = answer.find_next_sibling()
    while s:
        if s.name == 'strong' or s.find('strong'):
            break
        if s.name == 'p':
            txt += ' ' + s.get_text(strip=True)
        s = s.find_next_sibling()

    txt = ('\n' + ' '*31).join(textwrap.wrap(txt))

    print('{:<30} {:<70}'.format('Dror Ben Asher - CEO', txt), file=open("output.txt", "a"))

【问题讨论】:

  • 我认为你已经在路上了,你的第一次尝试看起来不错。您将希望用参数替换代码的硬编码部分。 Functions 将成为您的朋友。关于您的实际问题,SO 并不意味着作为代码编写服务,所以请尽力而为,当您遇到困难时,我们会在这里提供帮助。见How to AskWhat is On-Topic
  • 我阅读了您发布的功能链接,但我不明白如何让我的高管被“功能”找到和使用。你能举个例子吗?当然,我不希望这是一个代码编写服务。

标签: python html pandas


【解决方案1】:

为了给我的原始评论增添色彩,我将使用一个简单的示例。假设您有一些代码正在寻找字符串“Hello, World!”。在一个文件中,并且您希望将行号聚合到一个列表中。您的第一次尝试可能如下所示:

# where I will aggregate my results
line_numbers = []

with open('path/to/file.txt') as fh:
    for num, line in enumerate(fh):
        if 'Hello, World!' in line:
            line_numbers.append(num)

这段代码 sn-p 运行良好。但是,它仅适用于检查 'path/to/file.txt' 是否为 'Hello, World!'

现在,您希望能够更改要查找的字符串。这类似于说“我想检查不同的主管”。您可以使用函数来执行此操作。函数允许您为一段代码添加灵活性。在这个简单的例子中,我会这样做:

# Now I'm checking for a parameter string_to_search
# that I can change when I call the function
def match_in_file(string_to_search):
    line_numbers = []

    with open('path/to/file.txt') as fh:
        for num, line in enumerate(fh):
            if string_to_search in line:
                line_numbers.append(num)

    return line_numbers


# now I'm just calling that function here
line_numbers = match_in_file("Hello, World!")

您仍然需要更改代码,但如果您想搜索大量字符串,这将变得更加强大。如果我愿意,我可以在循环中使用这个函数(虽然我在实践中会做一些不同的事情),为了这个例子,我现在有能力这样做:

list_of_strings = [
    "Hello, World!",
    "Python",
    "Functions"
]

for s in list_of_strings:
    line_numbers = match_in_file(s)
    print(f"Found {s} on lines ", *line_numbers)

针对您的具体问题,您需要一个用于要搜索的executive 的参数。您的函数签名可能如下所示:

def find_executive(soup, executive):
    for answer in soup.select(f'p:contains("Question-and-Answer Session") ~ strong:contains({executive}) + p'):
        # rest of code

您已经阅读了soup,因此您无需再这样做了。您只需要更改您的 select 语句中的执行官。您想要 soup 的参数的原因是您不依赖于全局范围内的变量。

【讨论】:

    【解决方案2】:

    @C.Nivs 我的代码会是以下吗?因为我现在得到一个块错误:

    import textwrap
    import os
    from bs4 import BeautifulSoup
    
    directory ='C:/Research syntheses - Meta analysis/SeekingAlpha/'
    for filename in os.listdir(directory):
        if filename.endswith('.html'):
            fname = os.path.join(directory,filename)
            with open(fname, 'r') as f:
                soup = BeautifulSoup(f.read(),'html.parser')
    
    print('{:<30} {:<70}'.format('Name', 'Answer'))
    print('-' * 101)
    def find_executive(soup, executive):
        for answer in soup.select(f'p:contains("Question-and-Answer Session") ~ strong:contains({executive}) + p'):
        txt = answer.get_text(strip=True) 
        s = answer.find_next_sibling()
        while s:
            if s.name == 'strong' or s.find('strong'):
                break
            if s.name == 'p':
                txt += ' ' + s.get_text(strip=True)
            s = s.find_next_sibling()
    
        txt = ('\n' + ' '*31).join(textwrap.wrap(txt))
    
        print('{:<30} {:<70}'.format(func, txt), file=open("output.txt", "a"))
    

    【讨论】:

    • 对不起,我什至没有看到这个帖子。我会花一些时间来完成它。将来,对答案或您的问题的简单评论与编辑配对完美,否则,我将永远不会收到通知
    • @C.Nivs 太棒了。我认为仍然缺少的是我需要首先从 Div id=article_participants class="content_part hid"> P STRONG Executives STRONG Dror Ben Asher - 首席执行官 Ori Shilo - 副首席执行官、财务和运营人员Goldberg - 首席商务官 并将这些作为输入在问答环节中进行搜索。
    猜你喜欢
    • 2021-09-20
    • 2011-11-20
    • 1970-01-01
    • 2013-07-28
    • 2019-07-05
    • 2016-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多