🔥一个人走得远了,就会忘记自己为了什么而出发,希望你可以不忘初心,不要随波逐流,一直走下去🎶
🦋 欢迎关注🖱点赞👍收藏🌟留言🐾
🦄 本文由 程序喵正在路上 原创,CSDN首发!
💖 系列专栏:Python爬虫
🌠 首发时间:2022年7月31日
✅ 如果觉得博主的文章还不错的话,希望小伙伴们三连支持一下哦
通过编写程序来爬取互联网上的优秀资源,比如图片、音频、视频、数据等等
爬虫一定要用 Python 吗?
不是的,用 Java 也行,用 C语言 也行,编程语言只是工具,爬取数据是你的目的,至于用什么工具去达到目的都是可以的
那为什么大多数人都喜欢用 Python 来写爬虫呢?
因为 Python 写爬虫简单
在众多编程语言中,Python 对小白来说上手最快,语法最简单,更重要的是 Python 拥有非常多的关于爬虫能用到的第三方支持库
首先,爬虫在法律上是不被禁止的,也就是说法律是允许爬虫存在的,但是,爬虫也具有违法风险的。技术是无罪的,主要看你用它来干嘛,比如说有些人利用爬虫 + 一些黑客技术每秒钟对着小破站撸上十万八千次,那这个肯定是不被允许的
爬虫分为善意的爬虫和恶意的爬虫:
综上,为了避免煎精🐟,我们还是要安分守纪,时常优化自己的爬虫程序避免干扰到网站的正常运行,并且在使用爬取到的数据时,发现涉及到用户隐私和商业机密等敏感内容时,一定要及时终止爬取和传播
反爬机制:
反反爬策略:
robots.txt 协议:
可以使用的开发工具:
我们可以用百度来搜索得到想要的资源,而爬虫就是通过编写程序来模拟这一系列步骤
需求:用程序模拟浏览器,输入一个网址,从该网址中获取到资源或者内容
用 Python 搞定以上需求,特别简单
在 Python 中,我们可以直接用 urllib 模块来完成对浏览器的模拟工作,具体代码如下
from urllib.request import urlopen
resp = urlopen("http://www.baidu.com") # 打开百度
print(resp.read().decode("utf-8")) # 打印抓取到的内容
是不是很简单呢?
我们可以把抓取到的 html 内容全部写入文件中,然后和原版的百度进行对比,看看是否一致
from urllib.request import urlopen
resp = urlopen("http://www.baidu.com") # 打开百度
with open("mybaidu.html", mode="w", encoding="utf-8") as f: # 创建文件
f.write(resp.read().decode("utf-8")) # 读取到网页的页面源代码,保存到文件中
好的,这样我们就成功地从百度上爬取到了一个页面的源代码,就是几行代码这么简单
前面我们实现了一个网页的整体抓取工作,那么下面我们来了解一下 web 请求的全部过程,这样有助于后面我们遇到各种各样的网站时有入手的基本准则
那么到底我们浏览器在输入完网址到我们看到网页的整体内容,这个过程中究竟发生了什么?
这里我们以百度为例,在访问百度的时候,浏览器会把这一次请求发送到百度的服务器(百度的一台电脑),由服务器接收到这个请求,然后加载一些数据,返回给浏览器,再由浏览器进行显示。听起来好像是废话…
但是,这里面蕴含着一个极为重要的东西在里面,注意,百度的服务器返回给浏览器的不直接是页面,而是页面源代码(由 html、css、js 组成)。由浏览器把页面源代码进行执行,然后把执行之后的结果展示给用户
那么所有的数据都在页面源代码里面吗?
这里我们来了解一个新的概念——页面渲染
我们常见的页面渲染过程有两种:
服务器渲染
这个是最容易理解的, 也是最简单的。意思就是我们在请求到服务器的时候, 服务器直接把数据全部写入到 html 中, 我们浏览器就能直接拿到带有数据的 html 内容,比如
由于数据是直接写在 html 中的,所以我们能看到的数据在页面源代码中能是找得到的,这种网页⼀般都相对比较容易就能抓取到页面内容
前端JS渲染
这种就稍显麻烦了,这种机制⼀般是第⼀次请求服务器返回⼀堆 HTML 框架结构,然后再次请求到真正保存数据的服务器,由这个服务器返回数据,最后在浏览器上对数据进行加载
在网页按 F12 进入检查,再按下列步骤可以看到服务器后面传过来的数据
这样做的好处是服务器那边能缓解压力,而且分工明确,比较容易维护
了解了两种页面渲染,我们不难看出,有些时候,我们的数据不⼀定都是直接来自于页面源代码。如果你在页面源代码中找不到你要的数据时, 那很可能数据是存放在另⼀个请求里
协议:就是两个计算机之间为了能够流畅地进行沟通而设置的⼀个君子协定。常见的协议有 TCP/IP、SOAP协议、HTTP协议、SMTP协议 等等
HTTP协议,全称为 Hyper Text Transfer Protocol(超文本传输协议),是用于从万维网(WWW:World Wide Web)服务器传输超文本到本地浏览器的传送协议。简单来说,就是浏览器和服务器之间的数据交互遵守的就是 HTTP协议
HTTP协议 把⼀条消息分为三大块内容,无论是请求还是响应都是三块内容
请求:
1 请求行 ➪ 请求方式(get / host)请求url地址 协议
2 请求头 ➪ 放一些服务器要使用的附加信息
3 请求体 ➪ 一般放一些请求参数
响应:
1 状态行 ➪ 协议 状态码
2 响应头 ➪ 放一些客户端要使用的一些附加信息
3 响应体 ➪ 服务器返回的真正客户端要用的内容(HTML、json)等
在后面我们写爬虫的时候要格外注意请求头和响应头,这两个地方一般都隐含着一些比较重要的内容
请求头中最常见的一些重要内容(爬虫需要):
响应头中一些重要内容:
请求方式:
前面第一个爬虫程序,我们使用 urllib 来抓取页面源代码,这个是 Python 内置的一个模块。但是,它并不是我们常用的爬虫工具,常用的抓取页面的模块通常使用一个第三方模块 requests。这个模块的优势就是比 urllib 还要简单,并且处理各种请求都比较方便
既然是第三方模块,那就需要我们对该模块进行安装,安装方法如下:
按 win + R 进入控制台,然后输入下面这行命令即可
python -m pip install requests
如果安装速度慢的话可以改用国内的源进行下载安装:
python -m pip install -i http://pypi.tuna.tsinghua.edu.cn/simple requests
安装完,接下来我们来看看 requests 能带给我们什么?
代码实现:
# 案例1:抓取搜狗搜索内容
import requests
kw = input("请输入你要搜索的内容:")
url = f"https://www.sogou.com/web?query={kw}"
dic = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36 SLBrowser/7.0.0.12151 SLBChan/11"
}
resp = requests.get(url, headers=dic) # 处理一个小小的反爬
with open("sogou.html", mode="w", encoding="utf-8") as f:
f.write(resp.text)
运行结果:
接下来我们看一个有一点点复杂的案例
代码实现:
import requests
# 准备参数
kw = input("请输入你要翻译的英语单词:")
url = "https://fanyi.baidu.com/sug"
dic = {
"kw": kw # 这里要和抓包工具里的参数一样
}
# 请注意百度翻译的sug这个url,它是通过post方式进行提交的,所以我们也要模拟post请求
resp = requests.post(url, data=dic)
# 返回值是json,那就可以直接解析成json
resp_json = resp.json()
print(resp_json) # 直接打印看看,便于理解下面这个语句
print(resp_json['data'][0]['v']) # 拿到所返回字典中的内容
运行结果:
是不是很简单?
还有一些网站在进行请求的时候会校验你的客户端型号,比如案例3
代码实现:
import json
import requests
url = "https://movie.douban.com/j/chart/top_list"
# 重新封装参数
param = {
"type": "24",
"interval_id": "100:90",
"action": "",
"start": 0,
"limit": 20,
}
headers = {
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.182 Safari/537.36"
}
resp = requests.get(url=url, params=param, headers=headers)
list_data = resp.json()
print(list_data)
with open('douban.json', mode='w', encoding='utf-8') as f:
json.dump(list_data, fp=f, ensure_ascii=False)
print('over!!!')
运行结果:
🧸 这次的分享就到这里啦,继续加油哦^^
🐱 我是程序喵,陪你一点点进步
🍭 有出错的地方欢迎在评论区指出来,共同进步,谢谢啦