一、爬虫流程
获取网页内容——>解析网页内容——>储存或分析(可视化)数据
二、爬虫的注意事项
爬虫的遵循的规则:公民隐私数据不爬;受著作权保护的数据不爬;国家事务、国防建设尖端科技领域的计算机等不爬。
此外,
爬虫的请求数量和频率不能过高
网页有明显反爬限制(有些内容要登录才可查看或验证码)不要强行突破
查看网站的robots.txt文件,了解可爬取的网页路径范围
三、爬虫第一步:获取网页内容
(一)HTTP请求(HTTP是超文本传输协议)
HTTP请求是用户想要的到的内容
#请求行
POST/user/info HTTP/1.1#方法类型/资源路径/协议版本
#请求头
Host:www.example.com#主机域名,它结合资源路径可以得到一个完整的网址
User-Agent:curl/7.77.0
Accept:*/*#表示任意文件均可
#请求体
{"username":"林粒粒呀",
"email":"linliliya@hotmail.com"}#GET方法的请求体为空值
POST是方法类型,表示创建。在爬虫时,方法类型大多为GET。
(1)User-Agent:curl/7.77.0
(2)Accept:*/*
(二)HTTP响应
HTTP响应是服务器给用户的内容
#状态行
HTTP/1.1 200 OK
#响应头
Date:Fri,27 Jan 2023 02:10:48 GMT
Content-Type:text/html;charset=utf-8
#响应体
<!DOCTYPE html>
<head><title>首页</title></head>
<body><h1>林粒粒呀</h1><p>哈喽!</p></body>
</html>
状态行里的200表示客户端请求成功,下图是其他数字的含义,查询数字含义的链接
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Status/418
(三)Python发送请求
pip install requests #安装requests库
import requests #导入requests
response = requests.get("http://books.toscrape.com/")
if response.ok:
print(response.text)
else:
print("请求失败")
有时需要将爬虫程序伪装成浏览器,方法就是:加上head
import requests
head = {"User-Agent":"Mozilla/5.0(Windows NT 10.0; Win64; x64)"}
response = requests.get("http://books.toscrape.com/",headers = head)
if response.ok:
print(response.text)
else:
print("请求失败")
(四)例子,获取豆瓣网前250的电影
import requests
response=requests.get("https://movie.douban.com/top250")
print(response.status_code)
结果显示为418,4开头的就是不通过
于是,需要用到head把爬虫程序伪装成浏览器
import requests
headers ={
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36"
} #"User-Agent":后的代码可以在任意网站中,右键“检查”——>“Network”——>刷新网页——>找到"User-Agent":后面的代码并复制
response=requests.get("https://movie.douban.com/top250")
print(response.status_code)
结果显示为200,也就是请求成功
接着将响应的内容打印出来
print(response.text)
完整个代码如下
import requests #导入requests库
headers ={
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36"
} #伪装成浏览器向服务器发送请求
response=requests.get("https://movie.douban.com/top250")
print(response.status_code) #得到响应的结果是否成功
print(response.text) #将响应的内容打印出来
(2024年8月18日)
四、爬虫第二步:解析网页内容
(一)HTML的常用标签类型
(不太重要,了解一下HTML的组成就可以了)
<h1></h1>是标题标签
<p></p>是文本段落标签
<br>是强制换行,它没有闭合标签
<b></b>包围文字内容,进行加粗
<i></i>包围文字内容,进行斜体
<i></i>包围文字内容,加下划线
<img>是添加图片,它没有闭合标签,src指定需要有图片的来源或路径,还可以添加width和hight
<a></a>是放入链接,href指定链接,target="_self"表示当前页打开,target="_blank"表示从新窗口打开
<div></div>和<span></span>是容器,它们里面可以放入其他元素
列表
<ol> 是有序列表
<li></li>
</ol>
<ul> 是无序列表
<li></li>
</ul>
表格,有几个<tr> </tr>就有几行,有几个<td></td>该行就有几个单元格
<table>
<thread>
<tr>
<td>表头1</td>
<td>表头2</td>
</tr>
</thread>
<tbody>
<tr>
<td>111</td>
<td>222</td>
</tr>
<tr>
<td>333</td>
<td>444</td>
</tr>
</tbody>
</table>
下面可以创建一个html格式的文件,自己操练一下
<!DOCTYPE html>
<html>
<head>
<title>这是一个网页标题</title>
</head>
<body>
<div style="background-color:red;">
<h1>一级标题</h1>
<h2>二级标题</h2>
<h6>六级标题</h6>
<p>这是一个文本段落这是一个文本段落这是一个文本段落</p>
</div>
<p>这是<span style="background-color:blue;">一个</span><span style="background-color:yellow;">文本</span>段落</p>
<p>这是一个<br>文本段落</p>
<p><b>加粗</b>一个文本段落</p>
<p><i>斜体</i>一个文本段落</p>
<p><u>加下划线</u>一个文本段落</p>
<img src="https://gd-hbimg.huaban.com/f878bc34f9f64b86c7b991acfeb23d806b10ad9344bc7-8oTAsB_fw1200webp" width="500px">
<a href="https://huaban.com/materials" target="_blank">花瓣网</a>
<ol>
<li>第一项</li>
<li>第二项</li>
</ol>
<ul>
<li>苹果</li>
<li>香蕉</li>
</ul>
<table border="1">
<thead>
<tr>
<td>头部1</td>
<td>头部2</td>
<td>头部3</td>
</tr>
</thead>
<tbody>
<tr>
<td>111</td>
<td>222</td>
<td>333</td>
</tr>
<tr>
<td>444</td>
<td>555</td>
<td>666</td>
</tr>
<tr>
<td>777</td>
<td>888</td>
</tr>
</tbody>
</table>
</body>
</html>
(二)例子
还是爬取豆瓣网前250的电影,但只爬取电影标题
安装库
pip install bs4
from bs4 import BeautifulSoup
对爬取的内容进行解析
html = response.text #将爬取的内容用html保存
soup = BeautifulSoup(html,"html.parser")#对html进行解析,第二个参数是制定HTML解析器
由于只需要网页里前250电影的标题,因此需要筛选出含有电影标题的信息
通过查看豆瓣网前250电影网页(豆瓣电影 Top 250)的“检查”发现所有的标题都是span元素,它们的class值都是title,于是根据这两个共性去筛选
#找到所有class值为title的span元素
all_titles = soup.findAll("span",attrs={"class":"title"})#BeautifulSoup对象的findAll方法,第一个参数是标签名,第二个参数可选
for title in all_titles:#findAll返回的是一个可迭代对象,用for循环去迭代这个可迭代对象
print(title)
结果如下
可以发现它除了中文标题外,还给了span元素和电影原版标题(原版标题前面都有/),我们只需要中文标题,因此用以下代码实现
for title in all_titles:#删去span元素
title_string = title.string
if "/" not in title_string:#删除原版标题,只保留中文标题
print(title_string)
结果如下,可以发现只有25个电影标题,也就是网页的第一页
而我们需要250个标题,通过查看豆瓣网前250电影网页(豆瓣电影 Top 250)的其他页,可以发现,这里只有豆瓣网前250电影的第一页发现比起第一页,豆瓣网第二页网址后面多了start=25,第三页发现豆瓣网第二页网址后面多了start=50,...,最后一页网址后面多了start=225,所以用一个for循环来解决数字规律
for start_num in range(0,250,25):
print(start_num)
好了,现在我们已经找到了网页数字规律,那怎么结合到网页呢?当然是用for循环来解决
for start_num in range(0,250,25):
response=requests.get(f"https://movie.douban.com/top250?start={start_num}",headers=headers)
最后,获取和解析网页的全代码如下
pip install requests #安装requests库
pip install bs4
import requests #导入requests库
from bs4 import BeautifulSoup
headers ={
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36"
} #将程序伪装成网页
for start_num in range(0,250,25): #实现所有网页(250个电影)的获取
response=requests.get(f"https://movie.douban.com/top250?start={start_num}",headers=headers) #获取网页响应的内容
html = response.text #将网页响应的内容放在html
soup = BeautifulSoup(html,"html.parser") #对html进行解析
all_titles = soup.findAll("span",attrs={"class":"title"}) #得到电影标题
for title in all_titles: #筛选需要的中文标题
title_string = title.string
if "/" not in title_string:
print(title_string)
爬虫的过程是繁琐的,通过两天的学习,我只是当了知识的搬运工。所以,浅浅地谈一下接触爬虫的过程里的感悟。在接触爬虫的过程中,每一步可能都会遇到阻碍:第一步、网页内容获取。在这一步就很可能遭到网页的拒绝,虽然通过head进行伪装是一个好办法,但不一定每次都有效。第二步、网页内容解析,网页给了那么多内容,但不是所有我们都需要,这就要根据我们需要的内容(这里是电影标题)找到共性,像这个案例里“通过查看豆瓣网前250电影网页(豆瓣电影 Top 250)的“检查”发现所有的标题都是span元素,它们的class值都是title,于是根据这两个共性去筛选”。此外,还要注意,爬虫往往不是爬一页就够了,那么就需要找到其他页的地址的规律,然后用循环去打败它,成功解析出我们需要的网页内容。(2024年8月19日)
以上内容仅供笔者学习自用,如有错误,请各位大佬不吝赐教,待更新案例