赛博红兔的科技博客

CyberHongTu shares news, insights, and musings on fascinating technology subjects.


和我一起玩Python:50. Python网页爬虫Requests库

大家好,我是赛博红兔。之前我在介绍Python异步编写——多线程并发的时候,给大伙展示过这么一个例子。Python采用多线程并发从图片网站上下载大量的高清照片。这里我们就用到了Requests这个模块对Unsplash网站上的图片进行自动爬取。那么今后两期我们就专门来讲讲网页爬虫。我当然会从最基础最常用的讲起,最好你有一些HTTP、HTML和一些网页开发基础。没有也没关系,我会顺带地介绍一下,没有什么大问题。说到网页爬虫,它能自动帮我们上网、浏览网页、把有用的信息搬回来。比如你想收集豆瓣电影Top 100的电影名字,知乎热门话题的标题,最新论文的汇总,还有某些网站的高清壁纸和视频,爬虫都能轻松搞定。因为爬虫在爬取别人网站资源的同时是没有和网站主人打过招呼的,所以这项技术其实是介于道德和法律的灰色地带,在使用的时候需要关注网站的使用条款和用户协议。也有的网站会提供用户官方的API接口方便下载一些公开的信息。这个是大伙在使用爬虫的时候需要格外注意的,不要去违法。在Python里,可能最常用到的爬虫工具就是Requests,它的作用就像浏览器一样,负责发送请求、接收网页内容。不过,如果想要再进一步解析网页就需要用到BeautifulSoup之类的库了,这个我们下期再聊。首先,Requests是一个第三方库我们需要先安装。在命令窗口用pip安装即可:pip install requests。

好了,我们先来找一个用来学习爬虫的网站啊。Books to Scrape这个网站就是专门用来学习网页爬虫的模拟书店网站。它生来就是做这个的,所以鼓励你们多多地爬它。同样的网站还有Quotes to Scrape,httpbin,Fake Store之类的。

导入requests库之后,我们先来请求访问这个书店网站。我们把网站首页的url写上,用requests.get()向这个网址发起一个访问网页内容的请求。我们可以通过status_code来查看返回的状态码。不太了解网页状态码的朋友,我在这里简单介绍一下。网页状态码是服务器在响应客户端请求时返回的数字代码,用来表示请求的处理结果。比如说,2XX代表访问成功,像是这里的200就是一切正常。3XX就是网页重新定向到新的地址。4XX就是访问错误,大伙最熟悉的应该是这个404 Not Found。我们也可以用response.ok来打印一个布尔值,直截了当地来看看访问是否成功。True就是成功了。接下来,如果请求成功,我们就把网页的HTML内容打印出来。大家看到HTML源码有很多的标签和格式不是很很懂,没关系啊,我们用到的时候会简单介绍一下。当然,我们也可以直接在网站上用开发者工具来查看网页源代码结构,我这里用的是chrome浏览器啊,其他的浏览器也肯定同样的功能。直接在你想查看的地方点击右键然后选择inspect检查就可以查看了。你可以动态地看到每一部分对应的源代码。

import requests

# 检查网站响应状态
url = "https://books.toscrape.com"
response = requests.get(url)
print(response.status_code)
print(response.ok)

if response.status_code == 200:
    print(response.text)
else:
    print("请求失败,状态码:", response.status_code)

咱们再来看看如何爬取图片啊。我们在这里选一本书的封面图,点开之后右键保存它的网页地址。我们想要下载它就需要网页地址,我们把网址粘在上面。我们同样用get发起请求,下载这张图片。可以通过content这个属性来打印原始的二进制图片数据。当然,我们作为人类是看不懂二进制图画的是什么。所以,通过用文件写入的方式,把图片数据保存成一个jpg文件。我们就得到了这张封面图。我会把Python文件读取写入处理教学放在下面,不了解的朋友可以去看看。

除了content属性,还有headers属性,我们可以通过查看headers看到这张图的信息。比如说,最后修改的日期、什么格式的等等。

# 爬取图片
url = "https://books.toscrape.com/media/cache/fe/72/fe72f0532301ec28892ae79a629a293c.jpg"
response = requests.get(url)
print(response.content)

with open('bookcover.jpg', 'wb') as f:
    f.write(response.content)

# 爬取图片信息
url = "https://books.toscrape.com/media/cache/fe/72/fe72f0532301ec28892ae79a629a293c.jpg"
response = requests.get(url)
print(response.headers)

接下去我们来看看如何在get请求中添加查询参数,比如具体的网页页码和数量。我们这里展示用的是httpbin这个网站。简单介绍一下,这网站的目的是让我们在学习爬虫的时候,方便地来测试各种HTTP的请求操作。比如说,看你发出的请求长什么样,测试不同请求方法、参数和响应,验证客户端和服务器的交互之类的。我们具体来看看怎么来用。我们先定义一个参数字典,比如说“我要第2页,每页25条”。然后我们把这个字典作为参数喂给get方法。我们来打印看看我们发起请求之后返回来的内容。上面有我们的参数,IP地址,然后底下就是我们发起的完整网页请求的地址。一般我们注意观察网页这样的格式:第几页每页几条这样。通过喂参数的形式,我们就不用打出完整的这样的网址了。

# GET请求带参数
parameters = {'page': 2, 'count': 25}
url = "https://httpbin.org/get"
response = requests.get(url, params=parameters)
print(response.text)

然后,我们来看看用post方法来发出请求,并且附带表单数据,然后查看返回内容。这里,用httpbin的/post路径,它会返回发出的表单数据。我们同样把比如说用户名和密码的表单数据喂给post方法,然后来看看返回的内容。你看这里有我们输入的用户名和密码。注意啊,Requests会自动识别响应内容的类型,如果服务器返回的是JSON格式的数据。那么我们可以用json方法把它解析成Python的字典。这样我们就可以通过读取字典的键来读取用户名和密码信息了。

# POST请求提交表单数据
parameters = {'username': 'Hongtu', 'password': '12345'}
url = "https://httpbin.org/post"
response = requests.post(url, data=parameters)
print(response.text)
response_dict = response.json()
print(response_dict['form'])

有时候我们需要提交用户名和密码来请求登录网站对吧?像我们这里是一个需要身份验证的网址,用户名是Hongtu,密码是12345。我们先进入这个网址,看到需要我们输入用户名和密码。输入正确的用户名密码,就可以进入网页。同样我们可以用auth=()参数传入get请求用户名和密码的元组,来进行基本身份验证。我们来打印响应码和登录信息,看看是否验证成功。这里显示200,我们登录成功了。

url = "https://httpbin.org/basic-auth/Hongtu/12345"
response = requests.get(url, auth=('Hongtu', '12345'))
print(response.status_code)
print(response.text)

好啦,Requests这个库就先学到这里了!还有一些这个库高阶的用法,但是我这一期基本上覆盖了它90%的功能,相信大伙对网页爬虫的网页请求这块有一些基本的了解。大伙也试着去找上面介绍的练习网站跟着我实战一下。下一期呢,我们专门来看看对网页内容的解析和提取,这块才是核心啊。我们会用到BeautifulSoup,试着一起把我自己的博客给爬了。好了,本频道将同步在B站和油管上更新,如果你喜欢我的内容,请不要忘记点赞、订阅和分享,这样就不会错过我更新的内容,欢迎在评论区提出你的想法和建议。今天就到这里,再见吧!



Leave a comment