网页爬虫是一种通过程序自动抓取网页数据的技术。对于初学者来说,使用 Python 写一个简单的爬虫是一个很好的入门项目。Python 提供了许多强大的工具和库,如 requests 和 BeautifulSoup,可以帮助快速实现网页数据的爬取。
在本文中,我们将从爬虫的基本概念开始,逐步实现一个可以抓取网页内容的简单爬虫,并探讨如何改进爬虫以应对复杂场景。我们将从以下几个方面展开:
一、爬虫的基本概念
-
爬虫的定义
爬虫(Web Crawler)是一种自动化脚本或程序,它会模拟用户访问网页的行为,从而提取网页中的特定内容。
-
爬虫的主要工作流程
一个典型的爬虫任务通常包括以下步骤:
发送请求:通过 HTTP 协议访问目标网页,获取其 HTML 内容。
解析数据:对获取到的 HTML 进行解析,提取我们需要的数据。
存储数据:将提取到的数据保存到文件或数据库中,便于后续处理。
- 常用 Python 工具
requests:发送 HTTP 请求,获取网页内容。
BeautifulSoup:解析 HTML 或 XML 数据,提取特定内容。
re(正则表达式):对复杂文本模式进行匹配和提取。
pandas:对数据进行清洗和分析。
二、环境准备
-
安装 Python
确保你的计算机上已经安装了 Python(推荐使用 3.7 及以上版本)。如果尚未安装,可以从 Python 官方网站 下载并安装。
-
安装必要库
打开命令行或终端,运行以下命令安装我们需要的 Python 库:
pip install requests beautifulsoup4
1
requests:用于发送 HTTP 请求。
beautifulsoup4:用于解析 HTML 数据。
三、写第一个简单的爬虫
我们来实现一个简单的爬虫,它将抓取某个网页的标题和正文内容。
- 完整代码示例
以下代码实现了一个基本的爬虫:
import requests
from bs4 import BeautifulSoup
def simple_crawler(url):
try:
# 1. 发送请求
response = requests.get(url)
response.raise_for_status() # 检查请求是否成功
# 2. 解析网页内容
soup = BeautifulSoup(response.text, 'html.parser')
# 3. 提取标题和段落内容
title = soup.find('title').text # 获取网页标题
paragraphs = soup.find_all('p') # 获取所有段落内容
print(f"网页标题: {title}
")
print("网页内容:")
for p in paragraphs:
print(p.text)
except requests.exceptions.RequestException as e:
print(f"请求失败: {e}")
示例网址
url = "https://example.com" # 替换为你想爬取的网页地址
simple_crawler(url)
- 代码逐步解析
1)发送 HTTP 请求
response = requests.get(url)
1
使用 requests.get() 方法向目标网址发送 GET 请求。
返回的 response 对象包含网页的所有内容,包括 HTML 源代码。
2)检查请求状态
response.raise_for_status()
1
通过 raise_for_status() 检查请求是否成功。如果返回的 HTTP 状态码表示错误(如 404 或 500),会抛出异常。
3)解析 HTML 数据
soup = BeautifulSoup(response.text, 'html.parser')
1
BeautifulSoup 用于解析 HTML 内容,并将其转化为 Python 对象,方便后续操作。
第二个参数 'html.parser' 指定使用 Python 内置的 HTML 解析器。
4)提取网页内容
title = soup.find('title').text
paragraphs = soup.find_all('p')
find('title') 方法返回
标签的内容。</p>
<p>find_all('p') 方法返回所有段落标签 <p>,并以列表形式存储。</p>
<p>5)打印结果<br>
for p in paragraphs:<br>
print(p.text)</p>
<p>遍历提取到的段落内容,并打印每个段落的文本。<br>
四、改进爬虫功能</p>
<ol>
<li>添加请求头<br>
一些网站会检测爬虫程序并阻止访问。可以通过添加请求头来模拟浏览器访问。</li>
</ol>
<p>headers = {<br>
"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"<br>
}<br>
response = requests.get(url, headers=headers)</p>
<ol start="2">
<li>控制爬取频率<br>
为了避免对目标网站造成过高的负载,可以在每次请求后添加延时。</li>
</ol>
<p>import time</p>
<p>def delay_request(url):<br>
response = requests.get(url)<br>
time.sleep(2) # 等待 2 秒<br>
return response</p>
<ol start="3">
<li>保存数据<br>
将爬取的数据保存为文件或数据库。</li>
</ol>
<p>保存到文件:</p>
<p>with open("output.txt", "w", encoding="utf-8") as f:<br>
f.write(f"标题: {title}<br>
")<br>
for p in paragraphs:<br>
f.write(p.text + "<br>
")<br>
保存到 CSV 文件:</p>
<p>import csv</p>
<p>with open("output.csv", "w", newline="", encoding="utf-8") as csvfile:<br>
writer = csv.writer(csvfile)<br>
writer.writerow(["段落内容"])<br>
for p in paragraphs:<br>
writer.writerow([p.text])</p>
<p>五、应对复杂网页</p>
<ol>
<li>动态加载网页<br>
对于 JavaScript 渲染的网页,requests 无法获取完整内容,可以使用 selenium 或 playwright。</li>
</ol>
<p>示例(使用 selenium):</p>
<p>from selenium import webdriver</p>
<p>url = "<a href="https://example.com" target="_blank">https://example.com</a>"</p>
<h1 id="配置-webdriver">配置 WebDriver</h1>
<p>driver = webdriver.Chrome()<br>
driver.get(url)</p>
<h1 id="获取动态加载的内容">获取动态加载的内容</h1>
<p>html = driver.page_source<br>
print(html)</p>
<h1 id="关闭浏览器">关闭浏览器</h1>
<p>driver.quit()</p>
<ol start="2">
<li>爬取图片或文件<br>
import os</li>
</ol>
<h1 id="下载图片">下载图片</h1>
<p>img_url = "<a href="https://example.com/image.jpg" target="_blank">https://example.com/image.jpg</a>"<br>
response = requests.get(img_url)</p>
<h1 id="保存图片">保存图片</h1>
<p>with open("image.jpg", "wb") as f:<br>
f.write(response.content)</p>
<p>六、爬虫的注意事项</p>
<ol>
<li>遵守法律和道德<br>
避免违反法律:确保爬取行为符合目标网站的使用条款。</li>
</ol>
<p>尊重 robots.txt 文件:通过 robots.txt 查看目标网站的爬取限制。</p>
<ol start="2">
<li>处理异常<br>
对于网络请求失败、数据缺失等情况,添加异常处理逻辑:</li>
</ol>
<p>try:<br>
response = requests.get(url)<br>
response.raise_for_status()<br>
except requests.exceptions.RequestException as e:<br>
print(f"请求失败: {e}")</p>
<ol start="3">
<li>避免过于频繁的请求<br>
可以设置延时或使用代理 IP:</li>
</ol>
<p>proxies = {<br>
"http": "<a href="http://123.45.67.89:8080" target="_blank">http://123.45.67.89:8080</a>",<br>
"https": "<a href="http://123.45.67.89:8080" target="_blank">http://123.45.67.89:8080</a>"<br>
}<br>
response = requests.get(url, proxies=proxies)</p>
<p>最后关注灵活就业新动态,了解更多行业资讯、前沿技术请关注公众号:贤才宝(贤才宝https://www.51xcbw.com)<br>
<img src="https://img2024.cnblogs.com/blog/2525106/202503/2525106-20250311100437181-933636823.png" alt="" loading="lazy"></p>
<p>有没有软件行业离职或者失业状态的,公司招标需要可以给个人上基本社保,费用由公司承担,有需要的联系我,真实需求——拜托非诚勿扰,大家的时间都宝贵。<br>
徐女士13331180327</p>