快速了解网络爬虫
一、网络爬虫的介绍
网络爬虫(Web Crawler),又称网络蜘蛛、网络机器人,是一种按照一定规则自动抓取互联网信息的程序或脚本。它的核心作用是模拟人类浏览网页的行为,从网页中提取结构化或非结构化数据,为数据分析、信息聚合、内容存档等场景提供数据支持。
1. 爬虫的工作原理
网络爬虫的基本工作流程可概括为:
发起请求:向目标网页的服务器发送 HTTP/HTTPS 请求,获取网页响应。
解析内容:对服务器返回的网页数据(如 HTML、JSON 等)进行解析,提取需要的信息(如文本、图片 URL、链接等)。
存储数据:将提取的信息保存到本地文件(如 TXT、CSV)或数据库(如 MySQL、MongoDB)中。
递归爬取:根据解析出的新链接,重复上述过程,实现对多个网页的连续抓取。
2. 爬虫的应用场景
数据采集:如电商平台商品价格、评论抓取,用于市场分析;新闻网站内容抓取,用于舆情监控。
搜索引擎:搜索引擎的 “蜘蛛” 程序(如百度蜘蛛)通过爬取全网页面,建立索引,为用户提供搜索服务。
自动化测试:模拟用户操作,测试网页功能(如表单提交、登录流程)。
内容聚合:如 RSS 订阅工具,自动抓取多个网站的更新内容并汇总展示。
3. 爬虫的合法性与规范
爬虫并非 “无限制” 工具,需遵守以下规范:
尊重网站的robots.txt
协议(置于网站根目录,规定爬虫可爬取的范围)。
避免高频请求导致服务器负载过高(可设置请求间隔)。
不抓取受版权保护或隐私信息(如用户个人数据、付费内容)。
遵守网站的用户协议,部分网站明确禁止爬虫抓取。
二、requests库和网页源代码
1.requests库的安装
requests
是一个简洁易用的 HTTP 库,支持 GET、POST 等多种请求方式,能便捷地处理响应内容(如网页源码、JSON 数据)。相比 Python 内置的urllib
库,requests
语法更简洁,无需手动处理编码、Cookie 等细节。
安装方式:pip install requests -i Simple Index
2.网页源代码
网页源代码是网页的 “骨架”,由 HTML(超文本标记语言)编写,包含文本、图片、链接等信息的结构化描述。例如,一个简单的 HTML 源码片段:
<!DOCTYPE html>
<html><body><h1>欢迎来到我的网站</h1><p>这是一段文本</p><img src="image.jpg" alt="示例图片"></body>
</html>
爬虫通过解析 HTML 标签(如<h1>
、<p>
、<img>
),可提取对应的内容(标题、文本、图片 URL)。
3. 用 requests 获取网页源代码
通过requests.get()
发送 GET 请求,可获取网页的 HTML 源码:
import requests
# 目标网页URL
url = "https://www.baidu.com"
# 发送GET请求
response = requests.get(url)
# 设置编码(避免中文乱码)
response.encoding = "utf-8"
# 打印网页源码
print(response.text) # response.text返回字符串格式的源码
response.status_code
:返回状态码(如 200 表示请求成功,404 表示页面不存在)。response.content
:返回二进制格式的响应内容(适用于图片、视频等非文本资源)。
三、获取网页资源
除了 HTML 文本,网页中还包含图片、视频、文档等资源。爬虫可通过解析资源的 URL,下载这些文件到本地。
1. 资源 URL 的获取
网页中的资源(如图片)通常通过 HTML 标签的属性定义,例如:
<img src="https://example.com/images/pic.jpg" alt="示例图片">
其中src
属性的值即为图片的 URL。通过解析 HTML 源码中的src
、href
等属性,可提取资源的下载链接。
2. 下载资源的方法
使用requests
发送请求获取资源的二进制数据,再通过open()
函数写入本地文件:
示例:下载图片
import requests
# 图片URL
img_url = "https://img.example.com/pic.jpg"
# 发送请求获取图片二进制数据
response = requests.get(img_url)
# 保存图片到本地
with open("pic.jpg", "wb") as f: # "wb"表示二进制写入f.write(response.content) # response.content是二进制数据
print("图片下载完成")
示例:下载文档(如 PDF):
import requestspdf_url = "https://example.com/file.pdf"
response = requests.get(pdf_url)with open("document.pdf", "wb") as f:f.write(response.content)
print("PDF下载完成")
3. 批量下载资源
若需下载多个资源(如一个页面中的所有图片),可先提取所有图片 URL,再循环下载:
import requests
from bs4 import BeautifulSoup # 用于解析HTML(需安装:pip install beautifulsoup4)# 目标网页
url = "https://example.com/gallery"
response = requests.get(url)
soup = BeautifulSoup(response.text, "html.parser") # 解析HTML# 提取所有图片URL(假设图片标签为<img>,属性为src)
img_tags = soup.find_all("img")
img_urls = [img["src"] for img in img_tags if "src" in img.attrs]# 批量下载
for i, img_url in enumerate(img_urls):# 处理相对路径(如src为"/pic.jpg",需拼接域名)if not img_url.startswith("http"):img_url = f"https://example.com{img_url}"try:res = requests.get(img_url)with open(f"image_{i}.jpg", "wb") as f:f.write(res.content)print(f"下载成功:image_{i}.jpg")except Exception as e:print(f"下载失败:{img_url},错误:{e}")
四、提交信息到网页
很多网页需要用户提交信息(如登录、搜索、表单提交),此时需使用POST
请求(与获取数据的GET
请求不同)。requests
库的post()
方法可模拟表单提交。
1. GET 与 POST 的区别
GET:请求参数拼接在 URL 中(如https://example.com/search?keyword=python
),适用于获取数据,参数长度有限制。
POST:请求参数放在请求体中,不显示在 URL,适用于提交敏感信息(如密码)或大量数据。
2. 分析表单结构
提交信息前,需先确定表单的提交地址(action
)和参数(input
字段)。可通过查看网页源码(F12 开发者工具→Elements)找到form
标签:
<form action="/login" method="post"><input type="text" name="username" placeholder="用户名"><input type="password" name="password" placeholder="密码"><input type="hidden" name="token" value="abc123"> <!-- 隐藏字段,需一并提交 --><button type="submit">登录</button>
</form>
action="/login"
:表单提交的 URL(完整地址为网站域名 + /login
)。
method="post"
:提交方式为 POST。
name
属性:参数名(如username
、password
),提交时需与值对应。
3. 用 requests 提交 POST 请求
示例:模拟登录
import requests# 登录表单提交地址
login_url = "https://example.com/login"# 提交的参数(需与form中的name对应)
data = {"username": "myuser","password": "mypass","token": "abc123" # 隐藏字段,从网页源码获取
}# 发送POST请求
response = requests.post(login_url, data=data)# 检查登录结果(根据实际网页返回判断,如是否包含"登录成功")
if "登录成功" in response.text:print("登录成功")
else:print("登录失败")
4. 处理 JSON 数据提交
部分网页(如 API 接口)通过 JSON 格式提交数据,此时需用json
参数而非data
:
import requestsapi_url = "https://api.example.com/submit"# JSON格式的参数
json_data = {"name": "张三","age": 25,"hobby": ["编程", "阅读"]
}response = requests.post(api_url, json=json_data) # 自动设置Content-Type为application/json# 打印响应结果(假设返回JSON)
print(response.json())
五、会话
在网页交互中,用户的状态(如登录后保持登录状态)需通过 “会话(Session)” 维持。requests
的Session
对象可自动处理 Cookie,模拟用户的连续操作。
1. 为什么需要会话?
浏览器通过 Cookie 记录用户状态(如登录凭证),若每次请求都用新的requests.get()
或post()
,则 Cookie 不会保留,导致 “登录后访问需权限的页面” 失败。Session
可在多次请求间共享 Cookie,模拟真实用户的操作流程。
2. Session 的使用方法
示例:登录后访问需权限的页面
import requests# 创建Session对象(自动管理Cookie)
session = requests.Session()# 1. 先登录
login_url = "https://example.com/login"
data = {"username": "myuser", "password": "mypass"}
session.post(login_url, data=data) # 登录请求,Cookie被Session保存# 2. 访问需要登录的页面(无需再次提交Cookie)
user_center_url = "https://example.com/user"
response = session.get(user_center_url) # 自动携带登录后的Cookie# 验证是否成功访问
if "个人中心" in response.text:print("成功访问个人中心")
else:print("访问失败,可能未登录")# 关闭会话(可选)
session.close()
3. Session 的优势
自动处理 Cookie,无需手动提取和添加。
可设置全局请求头(如 User-Agent,模拟浏览器),避免重复代码:
session = requests.Session()
# 设置全局请求头
session.headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
}
# 后续请求会自动携带该头信息
六、代理服务器
当爬虫频繁请求同一网站时,服务器可能会封禁爬虫的 IP。代理服务器可作为 “中间层”,让请求通过代理 IP 发送,避免真实 IP 被封。
1. 代理服务器的作用
隐藏真实 IP:服务器看到的是代理 IP,保护爬虫的真实地址。
突破 IP 限制:部分网站对单 IP 的请求频率有限制,更换代理可绕过限制。
访问地域限制内容:通过特定地区的代理,可访问仅限该地区的资源。
2. 代理的类型
透明代理:服务器知道请求来自代理,且能获取真实 IP。
匿名代理:服务器知道请求来自代理,但无法获取真实 IP。
高匿代理:服务器无法判断请求来自代理,也无法获取真实 IP(爬虫首选)。
3. 在 requests 中使用代理
基本用法
import requests# 代理IP(格式:协议://IP:端口)
proxies = {"http": "http://123.45.67.89:8080","https": "https://123.45.67.89:8080" # HTTPS请求需对应HTTPS代理
}# 发送请求时指定代理
url = "https://example.com"
response = requests.get(url, proxies=proxies)
print(response.status_code)
4. 代理池的概念
单一代理 IP 可能不稳定(如失效、速度慢),实际应用中常使用 “代理池”:
维护一批可用代理 IP(通过爬虫抓取免费代理或购买付费代理)。
定期检测代理有效性,剔除失效 IP。
每次请求随机选择一个代理,降低被封风险。
注意事项
免费代理稳定性差,且可能泄露信息,生产环境建议使用付费代理。
即使使用代理,也需控制请求频率,避免滥用代理 IP 被封禁。
七、selenium库驱动浏览器
requests
适用于静态网页(HTML 直接返回内容),但对于动态网页(内容由 JavaScript 渲染,如滚动加载、点击后显示),需使用selenium
模拟浏览器操作。
1. selenium 与 requests 的区别
工具 | 特点 | 适用场景 |
---|---|---|
requests | 直接发送 HTTP 请求,速度快,资源占用少 | 静态网页,无 JavaScript 动态渲染 |
selenium | 驱动浏览器执行操作(如点击、输入) | 动态网页,需要模拟用户交互 |
2. selenium 的基本使用
安装 selenium:pip install selenium
-i Simple Index
安装浏览器的内核驱动
启动浏览器并加载网页:
import time
from selenium import webdriver
from selenium.webdriver.edge.options import Options
import re
import requests
chrome_options = Options()
chrome_options.binary_location = r"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe"
driver = webdriver.Edge(options=chrome_options)
driver.get('https://www.baidu.com/index.php?tn=68018901_58_oem_dg')
time.sleep(20)
上述代码通过驱动edge来打开百度页面。
获取渲染后的网页代码
from selenium import webdriver
from selenium.webdriver.edge.options import Options
edge_options = Options()
edge_options.binary_location=r"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe"
driver = webdriver.Edge(options=edge_options)
driver.get("https://www.baidu.com/index.php?tn=68018901_58_oem_dg")
print(driver.page_source)