Python 之用 BeautifulSoup 爬取网页简单示例

之前用于 Python 爬过一些网页,都写在程序里一直没有整理,最近工作上要用到一些新闻,爬取百度新闻的一些信息,于是将用 BeautifulSoup 爬取网页的一些步骤整理下。

目的

爬取百度体育新闻的几个板块信息,如NBA新闻,国内足球,国际足球等,链接是 http://news.baidu.com/sports。

分析

我用的是 Chrome 浏览器,按 F12 打开页面的请求,可以发现该页面的 NBA 新闻是链接一打开就获取的,剩下的几个板块则是后来通过接口请求后填充的。
在这里插入图片描述

步骤

1、使用 Python 的 requests 模块请求页面信息,获取 NBA 新闻
2、通过接口请求其他几个板块的信息

之前学习爬虫技术的时候,使用的是 Python 最原始的 urllib 库,后来推出了 requests 库,将 urllib 库的功能集成了。
可以直接使用 requests 的几个方法进行数据的获取,我写后面做接口测试自己使用 requests 的几个方法进行测试。

1 请求页面数据
通过查看网页源代码,定位到 NBA 新闻的位置,发现其信息都位于一个 class 为 ulist 的 ul 下面,然后我们可以定位到该地方,以下是代码演示。

import requests
from bs4 import BeautifulSoup
response = requests.get('http://news.baidu.com/sports')
#将网页内容作为 html 信息进行解析
resp = BeautifulSoup(response.text, "html.parser")

注意:
1)response.text 内容是字符串,而 response.content 是二进制数据,当我们爬取图片时 使用 response.content 进行保存
2)如果爬取的网页打印出来是乱码,可以通过如下代码来指定编码

 response.encoding = 'utf-8'

经过 BeautifulSoup 将网页内容处理以后,如果整个打印出来,可以看到内容都按照 HTML 有缩进的方式展现出来。
我们之前通过查看网页源代码找到 新闻的展现地址都在一个 class 为 ulist 的 ul 下面:
在这里插入图片描述
然后我们可以使用 findAll() 函数进行选择。
在这里 有两个用于寻找的函数,一个是 find() 函数,一个是 findAll() 函数。
前者 find() 函数的功能是找到一个符合搜索条件的就停止搜索,返回单个内容,
findAll() 返回的是页面所有符合搜索条件的内容,相当于是一个 所有 find() 内容的列表,即使只找到一个内容,也是元素为一的列表。
这两者相当于:

find() = findAll()[0]

寻找到NBA 新闻的代码如下:

uls = resp.findAll("ul", attrs = {"class": "ulist"})

以上的意思是,在 resp 中找到所有 class 属性值为 ulist 的 ul 标签。
返回的是一个列表。
通过查看,一共返回了四个 ul 标签,我们要寻找的 NBA 新闻为后两个。

uls = uls[2:]

对于 ul 下每一个 li 标签,我们需要获取 li 标签的标题和网页链接,方法如下:

for ul in uls:
	for li in ul.findAll('li'):
		title = li.text
		href = li.find('a')['href']

通过这种方法就获取到了 NBA 新闻的标题以及网页的连接。

2、接口获取数据
因为还要采集 CBA 新闻,足球等板块信息,通过观察页面,可以知道这几个板块的信息都是通过接口的方式请求之后进行填充的。
请求的 url 是:

http://news.baidu.com/widget?id=CbaNews&channel=sports&t=1572713532837

可以知道这是一个 get 请求,参数有三个, id, channel 以及 t。
其中, id 是定义新闻的类别,几个接口都是固定的,可以直接获取,
channel 是sports ,表明是体育新闻,在这个页面上是不变的,
t 是一个时间戳,之前和前端合作的时候,加上时间戳作用一般是防止浏览器取缓存信息,可以不传。

    news_params_list = [
            {"id":"WorldSoccerNews", "channel":"sports"}, 
            {"id":"ChinaSoccerNews", "channel":"sports"},   
            {"id":"CbaNews", "channel":"sports"},          
            {"id":"OtherNews", "channel":"sports"},         
            {"id":"LatestNews", "channel":"sports"},       
        ]

通过遍历上述的参数连接,将其挨个添加到请求链接的后面,就可以通过接口获取相应的信息。
Python 里有个库是用来将字典整合到链接的后面,这样我们就不用手动去拼凑链接:

import urllib
params = {"id":"WorldSoccerNews", "channel":"sports"}
url = 'http://news.baidu.com/widget'
suffix = urllib.parse.urlencode(params)
print(suffix)
# id=WorldSoccerNews&channel=sports
resq_url = url + '?' + suffix 
response = requests.get(resp_url)

其实之前是可以直接使用 requests.get(url, params) 这种方式的,不用自己拼凑链接,但是忘了 python3.4 还是 python3.6 里面,好像不支持这个方法了,我也没有再验证,但以上代码是确保可以使用的。

通过请求以上链接,打印出返回的内容,如下:

在这里插入图片描述
也是一串 HTML 代码,使用 BeautifulSoup 解析的方法同上,就可以获取其他版块的新闻信息了。

然后可以写一个存储的函数,将采集的信息存储到文件,或者 MySQL 数据库都行。

关于爬虫我有几点想要说的,

一、爬虫的意义,只是使用代码获取数据的一种方式。
二、爬虫的基础知识,我觉得要学习这种方式最好还是学习一点前端的知识,比如页面的组成,HTML,CSS,JS。最起码HTML的相关标签要了解。
三、爬取数据的方式,就示例来说,爬取数据的方式要么就是直接 requests.get 方法获取网页的所有数据,要么是通过接口向页面填充。
四、页面的 Python 解析库不只 BeautifulSoup 这一个,还有其他如 xpath 等,但我习惯用这个,我觉得使用起来蛮顺手的。
五、我提供的这个示例只是一个最简单的无需登录,无需验证,无需使用其他模拟 JS 请求的一个例子,其他的还有更复杂的方法可以学习一下。

  • 2
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值