【问题标题】:Get href from html with Beautiful Soup select or lxml xpath使用 Beautiful Soup select 或 lxml xpath 从 html 获取 href
【发布时间】:2019-07-02 19:52:20
【问题描述】:

我正在 Rotten Tomatoes 网站上为example here做一些网页抓取。

我将 Python 与 Beautiful Soup 和 lxml 模块一起使用。

我想提取电影信息,例如: - 类型:戏剧、音乐和表演艺术

  • 导演:Kirill Serebrennikov

  • 作者:Mikhail Idov、Lili Idova、Ivan Kapitonov、Kirill Serebrennikov、Natalya Naumenko

  • 作者(链接):/celebrity/michael_idov、/celebrity/lily_idova、/celebrity/ivan_kapitonov、/celebrity/kirill_serebrennikov、/celebrity/natalya_naumenko

我检查了页面 html 以获取路径指南:

                    <li class="meta-row clearfix">
                        <div class="meta-label subtle">Rating: </div>
                        <div class="meta-value">NR</div>
                    </li>


                    <li class="meta-row clearfix">
                        <div class="meta-label subtle">Genre: </div>
                        <div class="meta-value">

                                <a href="/browse/opening/?genres=9">Drama</a>, 

                                <a href="/browse/opening/?genres=12">Musical &amp; Performing Arts</a>

                        </div>
                    </li>


                    <li class="meta-row clearfix">
                        <div class="meta-label subtle">Directed By: </div>
                        <div class="meta-value">

                                <a href="/celebrity/kirill_serebrennikov">Kirill Serebrennikov</a>

                        </div>
                    </li>


                    <li class="meta-row clearfix">
                        <div class="meta-label subtle">Written By: </div>
                        <div class="meta-value">

                                <a href="/celebrity/michael_idov">Mikhail Idov</a>, 

                                <a href="/celebrity/lily_idova">Lili Idova</a>, 

                                <a href="/celebrity/ivan_kapitonov">Ivan Kapitonov</a>, 

                                <a href="/celebrity/kirill_serebrennikov">Kirill Serebrennikov</a>, 

                                <a href="/celebrity/natalya_naumenko">Natalya Naumenko</a>

                        </div>
                    </li>


                    <li class="meta-row clearfix">
                        <div class="meta-label subtle">In Theaters: </div>
                        <div class="meta-value">
                            <time datetime="2019-06-06T17:00:00-07:00">Jun 7, 2019</time>
                            <span style="text-transform:capitalize">&nbsp;limited</span>
                        </div>
                    </li>




                    <li class="meta-row clearfix">
                        <div class="meta-label subtle">Runtime: </div>
                        <div class="meta-value">
                            <time datetime="P126M">
                                126 minutes
                            </time>
                        </div>
                    </li>


                    <li class="meta-row clearfix">
                    <div class="meta-label subtle">Studio: </div>
                    <div class="meta-value">

                            <a href="http://sonypictures.ru/leto/" target="movie-studio">Gunpowder &amp; Sky</a>

                    </div>

            </li>

我创建了这样的 html 对象:

    page_response = requests.get(url, timeout=5)
    page_content = BeautifulSoup(page_response.content, "html.parser")
    tree = html.fromstring(page_response.content)

以 Writer 为例,因为我只需要元素上的文本,所以很容易得到:

page_content.select('div.meta-value')[3].getText()

或使用 xpart 进行评分:

tree.xpath('//div[@class="meta-value"]/text()')[0]

对于我遇到问题的所需 Writer 链接,要访问 html 块,我这样做:

page_content.select('div.meta-value')[3]

这给出了:

<div class="meta-value">
<a href="/celebrity/michael_idov">Mikhail Idov</a>, 

                                <a href="/celebrity/lily_idova">Lili Idova</a>, 

                                <a href="/celebrity/ivan_kapitonov">Ivan Kapitonov</a>, 

                                <a href="/celebrity/kirill_serebrennikov">Kirill Serebrennikov</a>, 

                                <a href="/celebrity/natalya_naumenko">Natalya Naumenko</a>

或者:

tree.xpath('//div[@class="meta-value"]')[3]

给予:

<Element div at 0x2915a4c54a8>

问题是我无法提取“href”。我想要的输出是:

/celebrity/michael_idov, /celebrity/lily_idova, /celebrity/ivan_kapitonov, /celebrity/kirill_serebrennikov, /celebrity/natalya_naumenko

我试过了:

page_content.select('div.meta-value')[3].get('href')
tree.xpath('//div[@class="meta-value"]')[3].get('href')
tree.xpath('//div[@class="meta-value"]/@href')[3]

所有结果为空或错误。 谁能帮我解决这个问题?

提前致谢! 干杯!

【问题讨论】:

  • 谢谢。这将返回页面中的所有 href,但是我只想要 page_content.select('div.meta-value')[3] 部分中的那些,对此有什么提示吗?我试过了,但没有成功,比如:for a in page_content.select('div.meta-value')[2]: print("Found the URL:", a['href'])

标签: python html xpath web-scraping beautifulsoup


【解决方案1】:

尝试以下脚本来获取您感兴趣的内容。确保使用不同的电影来测试它们。我想他们都会产生所需的输出。我试图避免使用任何硬编码索引来定位内容。

使用 css 选择器:

import requests
from bs4 import BeautifulSoup

r = requests.get('https://www.rottentomatoes.com/m/leto')
soup = BeautifulSoup(r.text,'lxml')

directed = soup.select_one(".meta-row:contains('Directed By') > .meta-value > a").text
written = [item.text for item in soup.select(".meta-row:contains('Written By') > .meta-value > a")]
written_links = [item.get("href") for item in soup.select(".meta-row:contains('Written By') > .meta-value > a")]
print(directed,written,written_links)

使用 xpath:

import requests
from lxml.html import fromstring

r = requests.get('https://www.rottentomatoes.com/m/leto')
root = fromstring(r.text)

directed = root.xpath("//*[contains(.,'Directed By')]/parent::*/*[@class='meta-value']/a/text()")
written = root.xpath("//*[contains(.,'Written By')]/parent::*/*[@class='meta-value']/a/text()")
written_links = root.xpath(".//*[contains(.,'Written By')]/parent::*/*[@class='meta-value']/a//@href")
print(directed,written,written_links)

在强制转换的情况下,我使用了列表解析,以便我可以在单个元素上使用 .strip() 来排除空格。不过,normalize-space() 是最理想的选择。

cast = [item.strip() for item in root.xpath("//*[contains(@class,'cast-item')]//a/span[@title]/text()")]

【讨论】:

  • xpath 工作完美,非常感谢。无论如何,我不知道你是怎么得到它的。对语法或您建议检查的一些资源的任何简短(我不想问太多)解释?再次感谢!
  • 首先查看this link 的内容,以基本了解如何创建相对xpath。
  • SIM,如果不是要求太多,请再帮我一个好吗?我真的无法理解语法。为了获得演员名单(Teo Yoo、Irina Starshenbaum 等),我仔细查看了 html 和你发给我的指南,但我想不出有用的东西。你能帮我一下吗?我真的试过了。谢谢!
  • 编辑加入演员@spcvalente。
  • 你真的很棒!我很乐意付给你一杯啤酒。我认为通过这些示例,我将能够对其进行调整并将其用于其他页面。非常感谢。
猜你喜欢
  • 1970-01-01
  • 2011-11-03
  • 2023-01-10
  • 2017-02-15
  • 1970-01-01
  • 1970-01-01
  • 2013-04-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多