龙空技术网

静态网页爬虫①

是迪伽娃 195

前言:

此刻我们对“pythoncss标签定位”大体比较着重,各位老铁们都需要学习一些“pythoncss标签定位”的相关文章。那么小编也在网摘上汇集了一些对于“pythoncss标签定位””的相关资讯,希望你们能喜欢,你们一起来学习一下吧!

处理数据

前面我们说过了通过 requests 库获取数据,这里我们要说如何处理数据

处理数据我们需要用到一个强大的第三方库——BeautifulSoup !

“美味的汤,绿色的浓汤,在热气腾腾的盖碗里装!谁不愿意尝一尝,这样的好汤?晚餐用的汤,美味的汤!”

BeautifulSoup 库的名字取自刘易斯·卡罗尔在《爱丽丝梦游仙境》里的同名诗歌。就像它在仙境中的说法一样,BeautifulSoup 尝试化平淡为神奇。它通过定位 HTML 标签来格式化和组织复杂的网页源代码,用简单易用的 Python 对象为我们展现出 HTML 结构信息。

处理数据分为两步:

解析数据:将网页源代码解析成 Python 能“读懂”的格式

提取数据:将网页源代码中无关数据过滤掉,只提取出我们所需要的数据

解析数据

我们以豆瓣读书 Top250 为例,它的网址是:。

我们来看看如何将其网页源代码解析成 BeautifulSoup 对象:

import requestsfrom bs4 import BeautifulSoupheaders = {  'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36'}res = requests.get(';, headers=headers)soup = BeautifulSoup(res.text, 'html.parser')

Tips:相比之前我们添加 headers 参数,这是为了应对豆瓣的反爬虫机制。

我们通过 from bs4 import BeautifulSoup 语句导入 BeautifulSoup,然后使用 BeautifulSoup(res.text, 'html.parser') 语句将网页源代码的字符串形式解析成了 BeautifulSoup 对象。

创建 BeautifulSoup 对象时需要传入两个参数,第一个参数是要解析的 HTML 文本,即网站源代码的字符串形式(res.text)。第二个参数是 解析HTML 的解析器,html.parser 是 Python 中内置的解析器,较为简单方便.

我们将网页源代码解析成了 BeautifulSoup 对象,如果我们将他打印出来会发现竟然和原来的网页源代码(也就是 res.text)一模一样!既然都一样,我们何苦费这么大力将网页源代码解析成 BeautifulSoup 对象 呢?

相比字符串,BeautifulSoup 对象 里有很多强大的方法和属性。通过这些方法和属性,我们就能方便快捷地提取出我们所需要的数据。

提取数据

BeautifulSoup 对象 里的方法和属性有很多,我们这里只提及其中最常用的一些,这些足以应付大多数场景。

find() 方法和 find_all() 方法

BeautifulSoup 对象 里的 find() 和 find_all() 是我们提取数据最常用的两个方法。借助它们,我们可以过滤掉 HTML 页面里的无用数据,轻松地找到我们需要的数据。

我们来看一下 find() 和 find_all() 的作用和区别:

我们可以通过例子来更好地理解他们:

假设我们获取到的网页源代码如下:

<div class="content">  <a href=";>登录/注册</a>  <h1>豆瓣读书 Top 250</h1>  <div class="artile">    <a href=";>豆瓣电影</a>    <div class="item">      <a href=";>追风筝的人</a>    </div>    <div class="item">      <a href=";>解忧杂货店</a>    </div>    <div class="item">      <a href=";>小王子</a>    </div>  </div></div>
soup = BeautifulSoup(res.text, 'html.parser')print(soup.find('a'))# 输出:<a href=";>登录/注册</a>print(soup.find_all('a'))# 输出:[# <a href=";>登录/注册</a>,# <a href=";>豆瓣电影</a>,# <a href=";>追风筝的人</a>,# <a href=";>解忧杂货店</a>,# <a href=";>小王子</a># ]

它俩的用法基本一样,都是传入 HTML 标签名称,返回符合该 HTML 标签的数据。区别是 find() 方法只返回第一个符合条件的标签,而 find_all() 方法返回所有符合条件的标签列表。他们的返回值分别是 BeautifulSoup 中的 Tag 对象 和由 Tag 对象组成的列表。(后面会提到)

除了传入 HTML 标签名称 外,这两个方法还支持传入 HTML 属性 进行筛选,返回符合条件的数据。举个例子:

# 查找 id='doubanapp-tip' 的 div 标签soup.find('div', id='doubanapp-tip')# 查找所有 class='rating_nums' 的 span 标签soup.find_all('span', class_='rating_nums')

class 和 id 这两个 HTML 属性 具有很强的标识性,因此是数据筛选中最常用的两个属性,我们要重点关注。

Tips:因为 class 是 Python 中定义类的关键字,因此用 class_ 表示 HTML 中的 class。

通过 id、class 等 HTML 属性的筛选,我们就可以快速准确的找到我们需要的数据。当一个条件无法精确定位到我们想要的数据时,我们还可以传入多个 HTML 属性进行筛选,返回同时符合这些条件的数据。

我们再来看个例子:

# 查找 id='doubanapp-tip' 且 class='rating_nums' 的 div 标签soup.find('div', id='doubanapp-tip', class_='rating_nums')

Tag对象

BeautifulSoup 将 HTML 中的元素封装成了 Tag 对象。和 BeautifulSoup 对象 一样,Tag 对象 里也有 find() 和 find_all() 方法。因此,我们可以不断地调用这两个方法,一层一层地找到我们需要的数据。我们还是以前面的 HTML 代码为例提取其中的书名:

<div class="content">  <a href=";>登录/注册</a>  <h1>豆瓣读书 Top 250</h1>  <div class="books">    <a href=";>豆瓣电影</a>    <div class="item">      <a href=";>追风筝的人</a>    </div>    <div class="item">      <a href=";>解忧杂货店</a>    </div>    <div class="item">      <a href=";>小王子</a>    </div>  </div></div>

我们可以看到,书名在 a 标签 中。但如果直接使用 soup.find_all(‘a’) 的话,第二行的“登录/注册”和第五行的“豆瓣电影”也会被获取到,因此我们需要将这些无效数据过滤掉。

我们分析一下不难发现,书名在 class=“item” 的 div 标签 里的 a 标签 内。我们只要先找到所有 class=“item” 的 div 标签,然后再找到其中的 a 标签 即可,因此我们可以像下面这样来获取书名的数据:

# 找到所有 class_='item' 的 div 标签items = soup.find_all('div', class_='item')for i in items:  # 找到 class_='item' 的 div 标签中的 a 标签  print(i.find('a'))# 输出:# <a href=";>追风筝的人</a># <a href=";>解忧杂货店</a># <a href=";>小王子</a>

这样,我们就找到了所有书名的数据。此时返回的还是 Tag 对象。如果我们只想要书名和对应的链接呢?这就用到了 Tag 对象 的 text 属性和 HTML 属性名取值。

items = soup.find_all('div', class_='item')for i in items:  tag = i.find('a')  # 获取 text 属性  name = tag.text  # 获取 href 属性值  link = tag['href']  print(name, link)# 输出:# 追风筝的人  解忧杂货店  小王子 

我们通过 Tag 对象 的 text 属性拿到了 a 标签里的文字内容,即 追风筝的人 等。然后我们通过和字典取值一样的方式,将 HTML 属性名 作为键,得到了对应属性的值。这里是以 href 属性为例,其他的 HTML 属性也同样可以。

我们来总结一下 Tag 对象 的常用属性和方法:

CSS选择器

有没有什么方法可以直接就找到我们需要的数据,而不用多次查找吗?

答案是肯定的,需要用到 CSS 选择器。

在 CSS 选择器中,# 代表 id,. 代表 class。比如:#login 表示 id=‘login’ 的所有元素,.item 表示 class=‘item’ 的所有元素。

我们也可以直接通过标签名选择对应的元素,比如:a 表示所有的 a 元素,p 表示所有的 p 元素。

它们也可以组合在一起,选择同时符合条件的元素,比如:a#login 表示所有 id=‘login’ 的 a 元素,p.item 表示所有 class=‘item’ 的 p 元素,#login.item 表示所有 id=‘login’ 且 class=‘item’ 的元素,.item.book 表示所有 class 同时为 item 和 book 的元素。

需要注意的是,选择同时符合条件的元素,选择器之间不能有空格,如果写成 .item .book 就是另一个意思了。这是新的知识点——子元素选择。

当两个选择器之间加了空格,表示子元素选择。还是以 .item .book 为例,它表示选择所有 class=‘item’ 的元素里面 class=‘book’ 的元素,即嵌套在 class=‘item’ 的元素里面 class=‘book’ 的元素。

这个嵌套可以是任意层级的,只要在里面就行,不要求直接嵌套在第一层。如果只需要直接嵌套在第一层符合条件的元素,可以用 > 分隔。比如:.item > .book。

来看个例子感受一下它们的区别:

from bs4 import BeautifulSouphtml = '''<div class="item">  <p class="book">小王子</p>  <div class="hot">    <p class="book">追风筝的人</p>  </div></div>'''soup = BeautifulSoup(html, 'html.parser')print(soup.select('.item.book'))# 输出:[]print(soup.select('.item .book'))# 输出:[<p class="book">小王子</p>, <p class="book">追风筝的人</p>]print(soup.select('.item > .book'))# 输出:[<p class="book">小王子</p>]

了解了 CSS 选择器的基本语法后,我们来看看如何在 BeautifulSoup 中使用。

BeautifulSoup 对象 有一个 select() 方法,我们将 CSS 选择器 传进去即可直接找到我们需要的元素。上面查找在 class=“item” 的 div 标签 里的 a 标签 的代码就可以这样写:

items = soup.select('div.item a')for i in items:  name = i.text  link = i['href']  print(name, link)# 输出:# 追风筝的人  解忧杂货店  小王子 
静态网页爬虫的过程

对于静态网页爬虫的过程,可以总结成下图:

我们现在对豆瓣top250中的前25个电影的名字以及名字进行爬取:

import requestsfrom bs4 import BeautifulSoupheaders = {    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.41 Safari/537.36 Edg/101.0.1210.32'}#首先对网页发出请求并获得响应req = requests.get(';,headers = headers)#将网页的源代码形式解析soup = BeautifulSoup(req.text,'html.parser')#进行元素的第一次提取result1 = soup.select('.item .pic')num = 0for i in result1:    num += 1    name = i.select('a img')[0]['alt']    link = i.select('a')[0]['href']    print(num,' ',name,link)

结果:

文章知识点与官方知识档案匹配,可进一步学习相关知识 , 免费领取有关于java面试题材料和讲解!

原文出处:

标签: #pythoncss标签定位