繁体   English   中英

使用 BeautifulSoup 获取 h2 标签下方的全文

[英]Get full text below h2 tag with BeautifulSoup

我正在尝试获取数据集的不同角色的描述和能力。 我遇到的问题是 h2 标签中似乎有一个 span 标签,在某些情况下,de p 标签之前有一个数字。 这是我面临的格式:

<h2><span class="mw-headline" id="Apariencia">Apariencia</span></h2>
<figure class="thumb tleft " style="width: 100px"> 
<p>...</p>
<p>...</p>
<p>...</p>
<h2><span class="mw-headline" id="Personalidad">Personalidad</span></h2>
<p>...</p>
<p>...</p>
<p>...</p>

我需要获取这些段落中的文本。

我尝试过类似的方法,但显然行不通。

import urllib.request
from bs4 import BeautifulSoup

fp = urllib.request.urlopen("https://jojo.fandom.com/es/wiki/Star_Platinum")
mybytes = fp.read()

html_doc = mybytes.decode("utf8")
fp.close()

soup = BeautifulSoup(html_doc, 'html.parser')

spans = soup.find_all('span', {"class": "mw-headline"})
for s in spans:
    print(s.nextSibling.getText)

您可以向后搜索以前的<h2>并将结果存储在字典中:

from bs4 import BeautifulSoup


html_doc = '''\
<h2><span class="mw-headline" id="Apariencia">Apariencia</span></h2>
<figure class="thumb tleft " style="width: 100px">
<p>T1 ...</p>
<p>T2 ...</p>
<p>T3 ...</p>
<h2><span class="mw-headline" id="Personalidad">Personalidad</span></h2>
<p>T4 ...</p>
<p>T5 ...</p>
<p>T6 ...</p>'''

soup = BeautifulSoup(html_doc, 'html.parser')

out = {}
for p in soup.select('p'):
    previous_h2 = p.find_previous('h2')
    out.setdefault(previous_h2.text, []).append(p.text)

print(out)

印刷:

{
    'Apariencia': ['T1 ...', 'T2 ...', 'T3 ...'], 
    'Personalidad': ['T4 ...', 'T5 ...', 'T6 ...']
}

我认为在这种情况下,带有.select选择器的 .select 会非常有用。

要获取所有节标题,您可以使用选择器h2:has(span.mw-headline[id]) 并通过嵌套在其中的spanid属性值(下面的hId )获得特定的 header,您可以使用下面的选择器hSel

hId = 'Personalidad' # for example
hSel = f'h2:has(span.mw-headline[id="{hId}"])'

然后,要获取 header之后的所有标签,您可以使用f'{hSel}~*' ,但您还需要过滤掉下一个header 之后的标签,以便只获取该部分中的标签,因此完整选择器将是

sSel = f'{hSel}~*:not({hSel}~h2~*):not(h2)'

[ :not({hSel}~h2~*)过滤掉下一个 header 之后的标签,并且:not(h2)过滤掉下一个 header 标签本身。]


利用这个,下面的 function 返回一个包含部分 header、文本和 html 的字典。

def get_wikiSection(header, wSoup, sec1Header='? Abstract ?'):
    sSel = 'h2:has(span.mw-headline[id])'
    sSel = f'*:has(~{sSel}):not({sSel}~*)'
    if not header: hId = hSel = None # [first section has no header]
    elif isinstance(header, str):
        hId, hSel = header, f'h2:has(span.mw-headline[id="{header}"])'
        header = wSoup.select_one(hSel)
        if not header: return {'errorMsg': f'Not found: {hSel}'} 
    else: hId = header.select_one('span.mw-headline[id]')['id'] 
    ## header SHOULD BE: None/hId/a tag containing span.mw-headline[id] ##

    if hId: 
        hSel = f'h2:has(span.mw-headline[id="{hId}"])'
        sSel = f'{hSel}~*:not({hSel}~h2~*):not(h2)'
        header = header.get_text(' ').strip()
    else: header = sec1Header
    
    sect = wSoup.select(sSel)
    sText = '\n'.join([s.get_text(' ').strip() for s in sect])
    sHtml = '\n'.join([''.join(s.prettify().splitlines()) for s in sect])
    if not sect: sText = sHtml = None
    return {'headerId': hId, 'sectionHeader': header, 
            'sectionText': sText, 'sectionHtml': sHtml}

例如, get_wikiSection('Personalidad', soup)将返回

{ 'headerId': 'Personalidad', 'sectionHeader': 'Personalidad', 'sectionText': 'Jotaro describió a Star Platinum como un ser muy violento. Suele ser silencioso, excepto cuando lanza golpes, gritando "ORA ORA ORA" en voz alta, bastante rápido y repetidamente. Con una cara relativamente humana ha demostrado tener expresiones tales como fruncir el ceño y sonreír.\nStar Platinum demuestra un tipo de interés en la auto-conservación, como se ve cuando detiene una bala que Jotaro dispara experimentalmente en su propia cabeza, protege a un Jotaro incapacitado de los ataques de DIO durante los efectos de su The World, y lo revive de cerca de la muerte directamente hacia latir su corazón (Sin embargo, considerando el papel pionero de Star Platinum en la serie, esta capacidad puede hablar principalmente de cualidades metafísicas o subconscientes genéricas para los usuarios de Stand).\nEn el manga original, Star Platinum desde el principio se ve con una sonrisa amplia y desconcertante. Más tarde, Star Platinum gana el rostro estoico de Jotaro, cualquier sonrisa futura va a advertir a la persona que se dirige a un gran dolor inminente.\nStar Platinum lleva el nombre de la carta del Tarot La Estrella, que simboliza el optimismo, el discernimiento y la esperanza.', 'sectionHtml': '<p> Jotaro describió a Star Platinum como un ser muy violento. Suele ser silencioso, excepto cuando lanza golpes, <a href="/es/wiki/Grito_de_Stand" title="Grito de Stand"> gritando </a> "ORA ORA ORA" en voz alta, bastante rápido y repetidamente. Con una cara relativamente humana ha demostrado tener expresiones tales como fruncir el ceño y sonreír.</p>\n<p> Star Platinum demuestra un tipo de interés en la auto-conservación, como se ve cuando detiene una bala que Jotaro dispara experimentalmente en su propia cabeza, protege a un Jotaro incapacitado de los ataques de <a href="/es/wiki/Dio_Brando" title="Dio Brando"> DIO </a> durante los efectos de su <a href="/es/wiki/The_World" title="The World"> The World </a>, y lo revive de cerca de la muerte directamente hacia latir su corazón (Sin embargo, considerando el papel pionero de Star Platinum en la serie, esta capacidad puede hablar principalmente de cualidades metafísicas o subconscientes genéricas para los usuarios de Stand).</p>\n<p> En el manga original, Star Platinum desde el principio se ve con una sonrisa amplia y desconcertante. Más tarde, Star Platinum gana el rostro estoico de Jotaro, cualquier sonrisa futura va a advertir a la persona que se dirige a un gran dolor inminente.</p>\n<p> Star Platinum lleva el nombre de la carta del Tarot <a class="extiw" href="http://en.wikipedia.org/wiki/es:La_Estrella_(Tarot)" title="wikipedia:es:La Estrella (Tarot)"> La Estrella </a>, que simboliza el optimismo, el discernimiento y la esperanza.</p>' }

如果你想要所有的部分:

h2Tags = soup.select('h2:has(span.mw-headline[id])')
wikiSections = [get_wikiSection(h, soup) for h in [None]+h2Tags]

生成的字典列表也可以像pd.DataFrame(wikiSections)一样简单地转换为 pandas DataFrame。

从自定义中提取文本<h2>在<div> BeautifulSoup 的元素</div><div id="text_translate"><p>嗨,我尝试从 h2 中提取名称,但发生错误,并且名称是从其他&lt;h2&gt; &lt;div class="poap serp-container lawyer"&gt;&lt;div class="gray_border"&gt;&lt;div class="col-lg-8 col-md-8 col-sm-9 col-xs-8 text_container"&gt;&lt;h2 class=""indigo_text&gt;Hi My name is Mark&lt;/h2&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt; &lt;h2&gt;的&lt;div class="poap serp-container lawyer"&gt;&lt;div class="gray_border"&gt;&lt;div class="col-lg-8 col-md-8 col-sm-9 col-xs-8 text_container"&gt;&lt;h2 class=""indigo_text&gt;Hi My name is Mark&lt;/h2&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;</p><pre> import requests import csv from bs4 import BeautifulSoup from itertools import zip_longest name = [] page_num = 1 phone = [] logo = [] website = [] links = [] while True: try: result = requests.get(f"https://attorneys.superlawyers.com/motor-vehicle-accidents/texas/houston/page{page_num}/") src = result.content soup = BeautifulSoup(src, "lxml") page_limit = int("126") if(page_num &gt; page_limit // 20): print("page ended, terminate") break names = soup.find_all("h2", {"class":"indigo_text"}) for i in range(len(names)): name.append(names[i].text.strip()) links.append(names[i].find("a").attrs["href"]) for link in links: result = requests.get(link) src = result.content soup = BeautifulSoup(src, "lxml") phones = soup.find("a", {"class":"profile-phone-header profile-contact-btn"}) phone.append(phones["href"]) logos = soup.find("div", {"class":"photo-container"}) logo.append(logos.find('img')['src']) websites = soup.find("a", {"class":"profile-website-header","id":"firm_website"}) website.append(websites.text.strip()) page_num +=1 print("page switched") except: print("error") break file_list = [name, phone, website, logo] exported = zip_longest(*file_list) with open("/Users/dsoky/Desktop/fonts/Moaaz.csv", "w") as myfile: wr = csv.writer(myfile) wr.writerow(["name","phone","website","logo"]) wr.writerows(exported)</pre><p> 我希望你们能帮我解决这个问题</p></div></h2>

[英]Extract text from custom <h2> in <div> elements by BeautifulSoup

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 BeautifulSoup - 无需课程即可获取 h2 文本 使用BeautifulSoup在两个h2标头之间获取文本 我想刮掉包含 img 标签的 h2 标签内的文本和普通的带有 beautifulsoup 的文本 用beautifulsoup刮<h2>标签 如何在 selenium python 中的 h2 标记内获取文本 如何获取下面带有特定 a 标签的 h2? 从自定义中提取文本<h2>在<div> BeautifulSoup 的元素</div><div id="text_translate"><p>嗨,我尝试从 h2 中提取名称,但发生错误,并且名称是从其他&lt;h2&gt; &lt;div class="poap serp-container lawyer"&gt;&lt;div class="gray_border"&gt;&lt;div class="col-lg-8 col-md-8 col-sm-9 col-xs-8 text_container"&gt;&lt;h2 class=""indigo_text&gt;Hi My name is Mark&lt;/h2&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt; &lt;h2&gt;的&lt;div class="poap serp-container lawyer"&gt;&lt;div class="gray_border"&gt;&lt;div class="col-lg-8 col-md-8 col-sm-9 col-xs-8 text_container"&gt;&lt;h2 class=""indigo_text&gt;Hi My name is Mark&lt;/h2&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;</p><pre> import requests import csv from bs4 import BeautifulSoup from itertools import zip_longest name = [] page_num = 1 phone = [] logo = [] website = [] links = [] while True: try: result = requests.get(f"https://attorneys.superlawyers.com/motor-vehicle-accidents/texas/houston/page{page_num}/") src = result.content soup = BeautifulSoup(src, "lxml") page_limit = int("126") if(page_num &gt; page_limit // 20): print("page ended, terminate") break names = soup.find_all("h2", {"class":"indigo_text"}) for i in range(len(names)): name.append(names[i].text.strip()) links.append(names[i].find("a").attrs["href"]) for link in links: result = requests.get(link) src = result.content soup = BeautifulSoup(src, "lxml") phones = soup.find("a", {"class":"profile-phone-header profile-contact-btn"}) phone.append(phones["href"]) logos = soup.find("div", {"class":"photo-container"}) logo.append(logos.find('img')['src']) websites = soup.find("a", {"class":"profile-website-header","id":"firm_website"}) website.append(websites.text.strip()) page_num +=1 print("page switched") except: print("error") break file_list = [name, phone, website, logo] exported = zip_longest(*file_list) with open("/Users/dsoky/Desktop/fonts/Moaaz.csv", "w") as myfile: wr = csv.writer(myfile) wr.writerow(["name","phone","website","logo"]) wr.writerows(exported)</pre><p> 我希望你们能帮我解决这个问题</p></div></h2> 当按值选择任何标签时,BeautifulSoup 仅返回标签的文本,期望返回完整的标签 使用 BeautifulSoup 获取两个 h2 元素之间的 p 数据 如何使用beautifulsoup提取h1标签文本
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM