一些关于自己学习Python的经历的内容,遇到的问题和思考等,方便以后查询和复习。
声明:本人学习是在扇贝编程通过网络学习的,相关的知识、案例来源于扇贝编程。如果使用请说明来源。
第1关:爬虫初体验
什么是网络爬虫
网络爬虫,简称爬虫,是一种按照一定的规则,自动地抓取互联网信息的程序或者脚本。
爬虫做的事情其实和蜘蛛是类似的,所以网络爬虫也被称为网络蜘蛛(spider)。蜘蛛在蜘蛛网上爬来爬去,把触手伸到蜘蛛网获取食物,而网络爬虫则是在互联网上爬来爬去,爬取我们需要的数据。
搜索引擎本质上就是爬虫,搜索引擎将互联网上的网页都爬取并存储起来。当我们搜索的时候,搜索引擎就从自己存储的网页里找到我们需要的结果并展示出来。
而我们可以通过爬虫获取海量的数据,所以爬虫是这一切的源头。
浏览器的工作原理
浏览器是怎么知道网站内容的呢?难道浏览器将所有网站的内容保存下来了?
当然不是这样!其实,浏览器偷偷地和 服务器 进行了交流,服务器将博客网站的内容传输给浏览器,浏览器收到后解析成你最终看到的网页。
拓展:浏览器通过 DNS(Domain
Name System)将域名转换成对应的 IP 地址,从而找到对应网站的服务器。图1
首先,我们在浏览器输入网址(URL)。然后浏览器去访问该网址对应的服务器,这个过程叫请求(request)。接着服务器将网站内容发送给浏览器,这个过程叫 响应(response)。
浏览器拿到服务器返回的内容后,一般都是网页的源代码。还需要浏览器将内容解析成我们能看懂的样子,也就是我们最终在浏览器里看到的网页。
其实,爬虫就是模拟浏览器的行为,从而获取网站的数据。
爬虫的工作原理
爬虫可以像浏览器一样向服务器发起请求,拿到服务器返回的数据后,可以根据我们设定的规则去提取需要的数据,数据处理完成后再将数据存储起来。图2
爬虫工作的三个步骤:
第一步:获取数据,爬虫会根据我们提供的网址,向服务器发起请求获取数据;
第二步:处理数据,对获取的数据进行处理,得到我们需要的部分;
第三步:存储数据,将处理后的数据保存起来,便于后续的使用和分析等。
爬虫中最常用的发起请求的第三方库——requests。requests 的中文文档页面(https://requests.kennethreitz.org/zh_CN/latest/)。
Tips:如果你的电脑上没安装Python,或者不知道具体如何安装 requests 库。请查看该文章:https://wpblog.x0y1.com/?p=34。
requests.get() 方法
import requests #导入 requests 模块
res =requests.get('https://wpblog.x0y1.com') # 发起请求
print(res)
# 输出:
使用 requests.get('网站地址') 方法向对应的网站发起了请求,然后我们将返回的结果存到了变量 res 中供后续使用。它的类型是 Response 对象,后面的 200 是状态码,表示请求成功。图3
Response 对象
通过 requests.get() 方法获取到了网页的数据,作为 Response 对象存到了变量 res,那么我们如何查看它的具体内容呢?
Response 对象的常用属性:
res.status_code 响应的HTTP状态码
res.text 相应内容的字符串形式
res.content 响应内容的二进制形式
res.encoding 响应内容的编码
res.status_code
import requests
res =requests.get('https://wpblog.x0y1.com')
print(res.status_code)
# 输出:200
这里的 200 就是响应的状态码,表示请求成功。当请求失败时会有不同的状态码,不同的状态码有不同的含义,常见的状态码如下:
1xx 消息 100 继续发出请求
2xx 请求成功 200 请求成功
3xx 重定向 301 永久重定向
4xx 客户端错误 404 找不到资源
5xx 服务端错误 503 服务不可用
练习:请求是否成功
通过 res.status_code 的值来判断请求是否成功,当其值为 200 时表示请求成功。
接下来请你补全下面的代码,当请求成功时打印出 请求成功,否则打印出 请求失败。
import requests
res =requests.get('https://wpblog.x0y1.com')
# 补全下行代码
if 200 <= res.status_code< 300:
# 答案直接用if res.status_code== 200:我理解2xx 是200到300之间的都可以,是否如此?
print('请求成功')
else:
print('请求失败')
res.text
res.text 返回的是服务器响应内容的字符串形式,也就是文本内容。
import requests
res = requests.get('https://wpblog.x0y1.com')
print(res.text)
练习:
试试用爬虫下载一个小说——孔乙己,它的网址是
https://apiv3.shanbay.com/codetime/articles/mnvdu。该网址返回的是小说的纯文本格式,源代码和内容是一样的。
import requests
# 获取孔乙己数据
res =requests.get('https://apiv3.shanbay.com/codetime/articles/mnvdu')
# 以写入的方式打开一个名为孔乙己的txt 文档
with open('孔乙己.txt', 'w') as file:
#将数据的字符串形式写入文件中
file.write(res.text)
open() 函数是 Python 中的内置函数,用于打开文件,返回值是一个 file 对象。
open() 函数接收的第一个参数为文件名,第二个参数为文件打开模式。打开模式默认为 r,是 read 的缩写,表示只读模式。即只能读取内容,不能修改内容。
常用的打开模式有 w(write,只写模式)、b(binary,二进制模式)和 a(append,追加模式,表示在文件末尾写入内容,不会从头开始覆盖原文件)。
Tips:在 w 和 a 模式下,如果你打开的文件不存在,那么 open() 函数会自动帮你创建一个。
这些打开模式还能两两组合,比如:rb 表示以二进制格式打开文件用于读取,wb 表示以二进制格式打开文件用于写入,ab 表示以二进制格式打开文件用于追加写入。
需要注意的是,使用 open() 函数打开文件,操作完毕后,最后一定要调用 file 对象的 close() 方法关闭该文件。所以一般我们像下面这样读写文件:
# 读取文件
file = open('文本.txt') #打开模式默认为 r,可省略
print(file.read()) #调用 read() 方法读取文件内容
file.close() #关闭文件
# 写入文件
file = open('文本.txt', 'w') #写入模式
file.write('扇贝编程') #调用 write() 方法写入内容
file.close() #关闭文件
为了避免忘记调用 close() 方法关闭文件,导致资源占用、文件内容丢失等问题,推荐使用with ... as ...语法,它在最后会自动帮你关闭文件。
# 普通写法
file = open('文本.txt','w') #写入模式
file.write('扇贝编程') #调用 write() 方法写入内容
file.close() #关闭文件
# 使用 with ... as
... 写法
with open('文本.txt','w') as file:
file.write('扇贝编程')
使用 with ... as ... 语法后,关闭文件的操作就可以省略了。不仅代码简洁了,也避免了忘记关闭文件的问题。
了解了文件操作之后,我们重新
import requests
# 获取孔乙己数据
res =requests.get('https://apiv3.shanbay.com/codetime/articles/mnvdu')
# 以写入的方式打开一个名为孔乙己的txt 文档
with open('孔乙己.txt','w') as file:
#将数据的字符串形式写入文件中
file.write(res.text)
获取到网页的响应后,以写入模式打开一个名为 孔乙己.txt 的文件,然后调用 write() 方法将响应内容的字符串形式写入到文件中,实现了小说的下载。同理,所有文本内容都可以通过这种方式进行下载,只需将 res.text 写入到文件当中保存即可。
res.content
除了文本内容的下载,爬虫还能下载图片、音频、视频等。
import requests
# 获取图片数据
res =requests.get('https://assets.baydn.com/baydn/public/codetime/xiaobei/info.jpg')
# 以二进制写入的方式打开一个名为info.jpg 的文件
with open('info.jpg', 'wb') as file:
#将数据的二进制形式写入文件中
file.write(res.content)
下载小说的步骤几乎一样。区别在于图片是用二进制写入的方式,将数据的二进制形式写入文件当中,而不是字符串形式。
所以 res.text 和res.content 的区别是:res.text 用于文本内容的获取、下载,res.content 用于图片、音频、视频等二进制内容的获取、下载。
res.encoding
编码是信息从一种形式或格式转换为另一种形式的过程,常见的编码方式有 ASCII、GBK、UTF-8 等。如果用和文件编码不同的方式去解码,我们就会得到一些乱码。
res.encoding 就是爬虫获取到数据的编码格式,requests 库会根据内容推测编码格式是什么,然后将 res.encoding 设成推测的格式,在访问 res.text 时使用该格式解码。
当推测的格式错误时,即出现乱码时,就需要我们手动给 res.encoding 赋值成正确的编码。