我应该如何使用 BeautifulSoup 在页面上的特定 dt 标签之间抓取 dd 标签中的文本?



我正在尝试从dd标签之间的dd类中提取文本(用于标记不同的日期(。我尝试了一种非常黑客的方法,但它的效果不够一致

timeDiv = mezzrowSource.find_all("dd", class_="orange event-date")
eventDiv = mezzrowSource.find_all("dd", class_="event")
index = 0 
for time in timeDiv:
returnValue[timeDiv[index].text] = eventDiv[index].text.strip()
if "8" in timeDiv[index+3].text or "4:30" in timeDiv[index+3].text:
break
index += 1 

以这种方式枚举会导致大多数时间从其他对象中提取过多的文本,但有时会从其他日期中提取事件。下面粘贴了相关部分的来源。有什么想法吗?

<dt class="purple">Sun, September 30th, 2018</dt>
<dd class="orange event-date">4:30 PM to 7:00 PM</dd>
<dd class="event"><a href="/events/4094-mezzrow-classical-salon-with-david-oei"
class="event-title">Mezzrow Classical Salon with David Oei</a>

</dd>
<dd class="orange event-date">8:00 PM to 10:30 PM</dd>
<dd class="event"><a href="/events/4144-luke-sellick-ron-blake-adam-birnbaum"
class="event-title">Luke Sellick, Ron Blake &amp; Adam Birnbaum</a>

</dd>
<dd class="orange event-date">11:00 PM to 1:00 AM</dd>
<dd class="event"><a href="/events/4099-ryo-sasaki-friends-after-hours"
class="event-title">Ryo Sasaki &amp; Friends &quot;After-hours&quot;</a>

</dd>

<dt class="purple">Mon, October 1st, 2018</dt>
<dd class="orange event-date">8:00 PM to 10:30 PM</dd>
<dd class="event"><a href="/events/4137-greg-ruggiero-murray-wall-steve-little"
class="event-title">Greg Ruggiero, Murray Wall &amp; Steve Little</a>

</dd>
<dd class="orange event-date">11:00 PM to 1:00 AM</dd>
<dd class="event"><a href="/events/4174-pasquale-grasso-after-hours"
class="event-title">Pasquale Grasso &quot;After-hours&quot;</a>

</dd>

预期输出是如下所示的字典: {'4:30 PM to 7:00 PM': 'Mezzrow Classical Salon with David Oei', '8:00 PM to 10:30 PM': 'Greg Ruggiero, Murray Wall & Steve Little', '11:00 PM to 1:00 AM': 'Pasquale Grasso 'After-hours"'}

如果我正确理解了这个问题,你可以使用 zip((:

mezzrowSource = BeautifulSoup(html , 'lxml')
timeDiv = [tag.get_text() for tag in mezzrowSource.find_all("dd", class_="orange event-date")]
eventDiv = [tag.get_text().strip() for tag in mezzrowSource.find_all("dd", class_="event")]
print(dict(zip(timeDiv, eventDiv)))

输出:

{'4:30 PM to 7:00 PM': 'Mezzrow Classical Salon with David Oei', '8:00 PM to 10:30 PM': 'Greg Ruggiero, Murray Wall & Steve Little', '11:00 PM to 1:00 AM': 'Pasquale Grasso "After-hours"'}

更新:

您想要数据的元素都是同级,即没有包含每组数据的元素,这使得更难根据需要对数据进行分组。唯一对您有利的是,带有日期的元素首先出现,然后是时间,然后是标题。时间和标题可以重复。因此,此方法选择我们想要的所有元素并迭代它们。在第一次迭代中,它将日期存储在字符串中,并创建包含时间和标题的元组列表。当它下次找到日期时,它会将日期和元组列表附加到字典中。在迭代结束时,它将最终日期和元组列表附加到字典中。这有点混乱,但这是由于HTML中缺乏结构。

from bs4 import BeautifulSoup
import requests
import re
import pprint
url = 'https://www.mezzrow.com/'
r = requests.get(url)
soup = BeautifulSoup(r.text , 'lxml')
ds = soup.find_all(True, {'class': re.compile('purple|event|orange event_date')})
ret = {}
tmp = []
i = None
for d in ds:
if d.attrs['class']==['purple']:
if i is not None:
ret[i] = tmp
tmp = []
i = (d.get_text())
elif d.attrs['class']==['orange', 'event-date']:
j =  d.get_text()
elif d.attrs['class']==['event']:
tmp.append ((j,d.get_text(strip=True)))
ret[i] = tmp
pp = pprint.PrettyPrinter(depth=6)
pp.pprint(ret)

输出:

{'Fri, October 12th, 2018': [('8:00 PM to 10:30 PM',
'Rossano Sportiello, Pasquale Grasso & Frank '
'Tate'),
('11:00 PM to 2:00 AM',
'Ben Paterson "After-hours"')],
'Fri, October 5th, 2018': [('8:00 PM to 10:30 PM',
'Vanessa Rubin, Brandon McCune, Kenny Davis & '
'Winard Harper'),
('11:00 PM to 2:00 AM',
'Joe Davidian "After-hours"')],
'Mon, October 1st, 2018': [('8:00 PM to 10:30 PM',
'Greg Ruggiero, Murray Wall & Steve Little'),
('11:00 PM to 1:00 AM',
'Pasquale Grasso "After-hours"')],
....

然后从字典对象中选择所需的日期。

最新更新