【问题标题】:Unable to get_text from select_one using BeautifulSoup无法使用 BeautifulSoup 从 select_one 中获取文本
【发布时间】:2019-12-13 21:06:48
【问题描述】:

我正在尝试从下面的 HTML 解析时间,但无法使用 get_textselect_one 来提取 <time class = "published-date relative-date" ... /time> 内的 data-published-datedatetime

<div class="content">
       <header>
        <h3 class="article-name">
         Curious Kids: Why is the Moon Called the Moon?
        </h3>
        <p class="byline">
         <span class="by-author">
          By
          <span style="white-space:nowrap">
           Toby Brown
          </span>
         </span>
         <time class="published-date relative-date" data-published-date="2019-12-13T12:00:28Z" datetime="2019-12-13T12:00:28Z">
         </time>
        </p>
       </header>

使用:

import requests
from bs4 import BeautifulSoup
url = 'https://www.space.com/news'
response = requests.get(url)
data = response.text
soup = BeautifulSoup(data, 'html.parser')

contents = soup.select('.content')
headlines = []
for item in contents:
  h_line = item.select_one('.article-name').get_text()
  author = item.select_one('.byline > span:nth-of-type(1) > span:nth-of-type(1)').get_text().strip()
  synopsis = item.select_one('.synopsis').get_text().strip() 
  date = item.select_one('.byline > time').get_text() 
  newsline = {'Headline': h_line, 'Author': author, 'Synopsis': synopsis, 'Date': dates}
  headlines.append(newsline) 

for line in headlines:   
  print(line)  

产生一个回溯错误,声称它是“NoneType”。此外,答案只能使用 BeautifulSoup 解析,不能使用 RegEx。

***更新: 我修改了答案以便能够在我的 for 循环中使用(这样我就可以遍历所有标题的源代码)

import requests
from bs4 import BeautifulSoup
url = 'https://www.space.com/news'
response = requests.get(url)
data = response.text
soup = BeautifulSoup(data, 'html.parser')

contents = soup.select('.content')
headlines = []
for item in contents:
  h_line = item.select_one('.article-name').get_text()
  author = item.select_one('.byline > span:nth-of-type(1) > span:nth-of-type(1)').get_text().strip()
  synopsis = item.select_one('.synopsis').get_text().strip() 
  dates = item.select_one('time').get('data-published-date')
  newsline = {'Headline': h_line, 'Author': author, 'Synopsis': synopsis, 'Date & Time Published': dates}
  headlines.append(newsline) 

for line in headlines:   
  print(line)   

【问题讨论】:

标签: python html python-3.x parsing beautifulsoup


【解决方案1】:
from bs4 import BeautifulSoup
data = """
<div class="content">
       <header>
        <h3 class="article-name">
         Curious Kids: Why is the Moon Called the Moon?
        </h3>
        <p class="byline">
         <span class="by-author">
          By
          <span style="white-space:nowrap">
           Toby Brown
          </span>
         </span>
         <time class="published-date relative-date" data-published-date="2019-12-13T12:00:28Z" datetime="2019-12-13T12:00:28Z">
         </time>
        </p>
       </header>
"""


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

for item in soup.findAll('time', {'class': 'published-date relative-date'}):
    print(item.get('data-published-date'))

输出:

2019-12-13T12:00:28Z

深度版:

import requests
from bs4 import BeautifulSoup

r = requests.get('https://www.space.com/news')
soup = BeautifulSoup(r.text, 'html.parser')

headline = []
author = []
syn = []
time = []
for item in soup.findAll('h3', {'class': 'article-name'}):
    headline.append(item.text)
for item in soup.findAll('span', {'style': 'white-space:nowrap'}):
    author.append(item.get_text(strip=True))
for item in soup.findAll('p', {'class': 'synopsis'}):
    syn.append(item.get_text(strip=True))
for item in soup.findAll('time', {'class': 'published-date relative-date'}):
    time.append(item.get('data-published-date'))

for item in zip(headline, author, syn, time):
    print(item)

【讨论】:

  • 这是非常低效的,因为您在这里运行四个单独的 for 循环来获得结果
  • @aws_apprentice 我很想看看你的one loop,这将导致大排队。
  • 当然,我刚刚发布了我的答案,它仅使用一个循环并且仍然可读,向 OP 展示如何以错误的方式执行此操作在我看来不是正确的答案
  • @aws_apprentice 如果您认为只有one loop,那么让我通知您,您正在循环访问contents,其中包括for loopfind_all
  • 但是 bs4 在幕后工作不是我关心的问题,不建议在正在发生的事情之上添加额外的循环,您的回答效率低下,在我看来不是正确的方法问题。教初学者添加更多循环不是一件好事
【解决方案2】:

这个解决方案应该更有效,因为它只循环一次。

import requests
from bs4 import BeautifulSoup

r = requests.get('https://www.space.com/news')
soup = BeautifulSoup(r.text, 'html.parser')
contents = soup.find_all('div', {'class': 'content'})

headlines = []
for content in contents:
    h_line = content.h3.text
    author = content.span.text.strip('\n').split('\n\n')[-1]
    synopsis = content.find('p', {'class': 'synopsis'}).text.strip('\n')
    dates = content.time['data-published-date']
    newsline = {'Headline': h_line, 'Author': author, 'Synopsis': synopsis, 'Date & Time Published': dates}
    headlines.append(newsline)

print(headlines[0])

{'Author': 'Doris Elin Urrutia ',
 'Date & Time Published': '2019-12-13T21:55:10Z',
 'Headline': 'Space Photos: The Most Amazing Images This Week!',
 'Synopsis': 'Here are our picks for the most amazing space photos of the week.'}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-21
    • 2016-03-24
    • 2020-11-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多