爬虫入门re+bs4
目录前言
1. 导入必要的库
2. 界说获取网页HTML内容的函数 get_html
3. 界说获取数据的函数 get_data
4. 界说获取文章正文内容的函数 content_text
5. 界说获取单条课程数据的函数 get_one_course_data
6. 界说保存数据的函数 `save_data`
7. 界说文件名合法化处理函数 `sanitize_filename`
8. 主步伐
前言
在信息爆炸的时代,互联网已成为数据获取的核心渠道。从学术研究到商业分析,从新闻监控到用户行为洞察,数据的价值日益凸显。而网络爬虫(Web Crawler)作为主动化获取网络数据的核心技能,正扮演着越来越重要的角色。本案例将通过一个完备的 Python 爬虫案例,构建高效、可靠的爬虫体系,实现对中文日报网站内容的主动化抓取与结构化存储。
说明
遵守法律法规:确保爬取的内容符合目标网站的 robots 协议,避免侵犯他人知识产权。
合理控制请求频率:通过time.sleep()等机制低落对目标服务器的压力,防止 IP 被封禁。
动态调解策略:网页结构大概变化,需根据实际情况修改解析逻辑(如 CSS 选择器)。
实战导向:以 中国日报(China Daily) 真实网页为目标,演示从页面解析到数据存储的全流程,代码可直接复用于雷同网站。
技能覆盖:涵盖 HTTP 请求、HTML 解析、反爬策略、数据清洗、文件存储等核心技能,联合requests、BeautifulSoup、pandas等主流库,提拔代码实战能力。
模块化设计:通过函数封装实现功能解耦,低落代码复杂度,便于后续扩展与维护。
反爬与稳定性:包含请求头伪装、异常处理、延时机制等策略,减少被目标网站封禁的风险。
把握 Python 爬虫的根本架构与工作流程;
学会利用BeautifulSoup解析复杂 HTML 结构;
明确并处理网页反爬机制(如请求头伪装、延时控制);
实现数据的清洗、存储与长期化(CSV 文件);
相识图片下载与文件名合法化处理本领。
实用场景
本案例得当以下读者:
对 Python 爬虫感兴趣的初学者;
必要批量获取公开网络数据的开发者;
希望相识新闻聚合、舆情监控等应用的从业者。
代码亮点
智能编码处理:利用chardet主动检测网页编码,避免乱码问题;
结构化数据存储:通过pandas将数据保存为 CSV 文件,便于后续分析;
图片当地化存储:主动下载文章配图并命名,支持特别字符过滤;
分页爬取支持:主动识别 “下一页” 链接,实现无限翻页抓取。
后续扩展建议
添加代理池以应对反爬限定;
集成 Scrapy 框架提拔爬取效率;
增长数据去重与增量更新功能;
联合 NLP 技能对新闻内容进行情感分析。
构建高效的中文日报内容抓取体系
1. 导入必要的库
import os.path
import requests
import chardet
import time
from bs4 import BeautifulSoup
import pandas as pd
import re
os.path:用于处理文件路径相干操作,比方检查文件是否存在
requests:用于发送HTTP请求,获取网页内容
chardet:用于检测网页内容的字符编码
time:用于添加延时,避免对目标网站造成过大压力
BeautifulSoup:用于解析HTML和XML文档,方便提取所需信息
pandas:用于数据处理和保存,将爬取的数据保存为CSV文件
re:用于正则表达式操作,比方文件名的合法化处理
2. 界说获取网页HTML内容的函数 get_html
def get_html(url):
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36 Edg/124.0.0.0'
}
try:
# 发送请求
response = requests.get(url, headers=headers)
# 检查请求响应状态码
response.raise_for_status()
# 设置相应内容字符编码
response.encoding = chardet.detect(response.content)['encoding']
return response.text
except Exception as e:
print(e)
finally:
time.sleep(2)
功能:发送HTTP请求获取指定URL的网页内容,并处理字符编码
步骤:
1. 设置请求头 `headers`,模仿欣赏器访问,避免被网站识别为爬虫
2. 利用 `requests.get` 方法发送请求
3. 利用 `raise_for_status` 方法检查响应状态码,如果状态码不是200,抛出异常
4. 利用 `chardet` 检测网页内容的字符编码,并设置响应的编码
5. 返回网页的文本内容
6. 无论请求是否成功,最后都利用 `time.sleep(2)` 暂停2秒,避免频繁请求
3. 界说获取数据的函数 get_data
def get_data(html):
# 解析HTML文本
bs = BeautifulSoup(html, 'lxml')
# 查找第一个符合class_="left-liebiao"条件div的标签
div_tag_one = bs.find('div', class_="left-liebiao")
# 查找所有符合class_="busBox3"条件的div标签
div_tags = div_tag_one.find_all('div', class_="busBox3")
return
功能:从网页HTML内容中提取所需的数据。
步骤:
1. 利用 `BeautifulSoup` 解析HTML文本
2. 查找第一个 `class` 为 `left-liebiao` 的 `div` 标签
3. 在该 `div` 标签内查找所有 `class` 为 `busBox3` 的 `div` 标签
4. 遍历这些 `div` 标签,调用 `get_one_course_data` 函数提取每条数据
4. 界说获取文章正文内容的函数 content_text
def content_text(content_url):
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36 Edg/124.0.0.0'
}
# 发送请求
response = requests.get(content_url)
# 检查请求响应状态码
response.raise_for_status()
# 设置相应内容字符编码
response.encoding = chardet.detect(response.content)['encoding']
html = response.text
# 解析HTML文本
bs = BeautifulSoup(html, 'lxml')
# 查找所有符合id="Content"条件的div标签
div = bs.find('div', id="Content")
p_tags = div.find_all('p')
# 写入文本
texts =
texts = ''.join(texts)
return texts
功能:根据文章链接获取文章的正文内容。
步骤:
1. 设置请求头,发送HTTP请求。
2. 检查响应状态码,设置字符编码。
3. 利用 `BeautifulSoup` 解析HTML文本。
4. 查找 `id` 为 `Content` 的 `div` 标签。
5. 在该 `div` 标签内查找所有 `p` 标签。
6. 提取 `p` 标签的文本内容,并拼接成一个字符串返回。
5. 界说获取单条课程数据的函数 get_one_course_data
def get_one_course_data(div_tag):
# 找到标题内容
title_tag = div_tag.select_one('div > div:nth-child(2) > h3 > a')
title = title_tag.text.strip() if title_tag is not None else None
# 保存图片
img_tag = div_tag.select_one('img')
print(img_tag)
if img_tag:
img_url = img_tag.get('src')
img_url = 'https:' + img_url
img = requests.get(img_url)
img.raise_for_status()
img_name = sanitize_filename(title)
print(img_name)
file_name = f'test/{img_name}.jpg'
with open(file_name, 'wb') as f:
f.write(img.content)
# 找到摘要内容
abstract_tag = div_tag.select_one('div > div:nth-child(2) > p')
abstract = ''.join()
# 找到日期内容
date_tag = div_tag.select_one('div > div:nth-child(2) > p > b')
date = date_tag.text.strip() if date_tag is not None else None
# 爬取正文内容
content_url = 'https:' + title_tag.get('href')
content = content_text(content_url)
return title, abstract, date, content
功能:从单个 `div` 标签中提取标题、图片、择要、日期和正文内容。
步骤:
1. 利用 `select_one` 方法找到标题标签,并提取标题文本
2. 找到图片标签,获取图片链接,发送请求下载图片,并保存到当地。利用 `sanitize_filename` 函数对文件名进行合法化处理
3. 找到择要标签,提取择要内容
4. 找到日期标签,提取日期内容
5. 构建文章链接,调用 `content_text` 函数获取文章正文内容
6. 返回标题、择要、日期和正文内容
6. 界说保存数据的函数 `save_data`
def save_data(data, file_name):
df = pd.DataFrame(data, columns=['标题', '摘要', '日期', '详情(新闻内容)'])
if not os.path.exists(file_name):
df.to_csv(file_name,
encoding='utf-8-sig',# 编码为utf-8-sig
header=True,# 添加列名
index=False)# 不添加行索引
else:
df.to_csv(file_name,
encoding='utf-8-sig',# 编码为utf-8-sig
header=False,# 不加列名
index=False,# 不添加行索引
mode='a')# 追加数据
return
功能:将爬取的数据保存为CSV文件。
步骤:
1. 利用 `pandas` 的 `DataFrame` 方法将数据转换为数据框
2. 检查文件是否存在,如果不存在,则创建文件并添加列名;如果存在,则追加数据,不添加列名
7. 界说文件名合法化处理函数 `sanitize_filename`
def sanitize_filename(filename):
# 定义正则表达式,匹配所有不合法的字符
pattern = r'[\\*?:"<>|【】]'
# 将不合法的字符替换为下划线
return re.sub(pattern, '_', filename)
功能:将文件名中的不合法字符替换为下划线,避免保存文件时出现错误
8. 主步伐
if __name__ == '__main__':
# 爬取地址
url = f'https://china.chinadaily.com.cn/5bd5639ca3101a87ca8ff636/page_39.html'# 如果改成其它的url,可能有反爬策略和不同的内容定位策略+翻页规则
while url:
# 获取网页文本内容
html = get_html(url)
if not html:
break
# 获取关键信息
data = get_data(html)
# 写入文件
file_name = '中文日报.csv'
save_data(data, file_name)
# 解析HTML文本,查找下一页链接
bs = BeautifulSoup(html, 'lxml')
next_page_tag = bs.find('a', text='下一页')
if next_page_tag:
url = 'https:' + next_page_tag.get('href')
else:
url = None
功能:从指定URL开始爬取数据,直到没有下一页为止。
步骤:
1. 界说初始爬取URL
2. 利用 `while` 循环,只要 `url` 不为空,就继续爬取
3. 调用 `get_html` 函数获取网页HTML内容
4. 调用 `get_data` 函数提取关键信息
5. 调用 `save_data` 函数将数据保存到CSV文件
6. 解析HTML文本,查找下一页链接。如果找到,则更新 `url`;否则,将 `url` 置为 `None`,结束循环
运行结果:
https://i-blog.csdnimg.cn/direct/71141c82d1ee4f94a9c7b09d022303ae.png
保存的图片如果没有明确指定文件路径则默认到当前工作目录下,保存的图片:
https://i-blog.csdnimg.cn/direct/b951b62847554652867f3bd3f30edd61.png
这个爬虫代码的案例主要功能是从指定的网页开始,爬取新闻标题、择要、日期、正文内容和图片,并将数据保存为CSV文件。代码通过界说多个函数,将不同的功能模块化,进步了代码的可读性和可维护性。通过添加了异常处理和延时机制,避免对目标网站造成过大压力。完备代码:
import os.path
import requests
import chardet
import time
from bs4 import BeautifulSoup
import pandas as pd
import re
def get_html(url): headers = { 'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36 Edg/124.0.0.0' } try: # 发送请求 response = requests.get(url,headers=headers) # 检查请求响应状态码 response.raise_for_status() # 设置相应内容字符编码 response.encoding = chardet.detect(response.content)['encoding'] return response.text except Exception as e: print(e) finally: time.sleep(2)def get_data(html): # 解析HTML文本 bs = BeautifulSoup(html,'lxml') # 查找第一个符合class_="left-liebiao"条件div的标签 div_tag_one = bs.find('div',class_="left-liebiao") # 查找所有符合class_="busBox3"条件的div标签 div_tags = div_tag_one.find_all('div',class_="busBox3") return def content_text(content_url): headers = { 'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36 Edg/124.0.0.0' } # 发送请求 response = requests.get(content_url) # 检查请求响应状态码 response.raise_for_status() # 设置相应内容字符编码 response.encoding = chardet.detect(response.content)['encoding'] html = response.text # 解析HTML文本 bs = BeautifulSoup(html, 'lxml') # 查找所有符合id="Content"条件的div标签 div = bs.find('div', id="Content") p_tags = div.find_all('p') # 写入文本 texts = texts = ''.join(texts) return textsdef get_one_course_data(div_tag): # 找到标题内容 title_tag = div_tag.select_one('div > div:nth-child(2) > h3 > a') title = title_tag.text.strip() if title_tag is not None else None # 保存图片 img_tag = div_tag.select_one('img') print(img_tag) if img_tag: img_url = img_tag.get('src') img_url = 'https:' + img_url img = requests.get(img_url) img.raise_for_status() img_name = sanitize_filename(title) print(img_name) file_name = f'test/{img_name}.jpg' with open(file_name, 'wb') as f: f.write(img.content) # 找到择要内容 abstract_tag = div_tag.select_one('div > div:nth-child(2) > p') abstract = ''.join() # 找到日期内容 date_tag = div_tag.select_one('div > div:nth-child(2) > p > b') date = date_tag.text.strip() if date_tag is not None else None # 爬取正文内容 content_url = 'https:' + title_tag.get('href') content = content_text(content_url) return title,abstract,date,contentdef save_data(data,file_name): df = pd.DataFrame(data,columns=['标题','择要','日期','详情(新闻内容)']) if not os.path.exists(file_name): df.to_csv(file_name, encoding='utf-8-sig',# 编码为utf-8-sig header=True,# 添加列名 index=False)# 不添加行索引 else: df.to_csv(file_name, encoding='utf-8-sig',# 编码为utf-8-sig header=False,# 不加列名 index=False,# 不添加行索引 mode='a')# 追加数据 returndef sanitize_filename(filename):
# 定义正则表达式,匹配所有不合法的字符
pattern = r'[\\*?:"<>|【】]'
# 将不合法的字符替换为下划线
return re.sub(pattern, '_', filename)
if __name__=='__main__': # 爬取地点 url = f'https://china.chinadaily.com.cn/5bd5639ca3101a87ca8ff636/page_39.html' # 如果改成其它的url,大概有反爬策略和不同的内容定位策略+翻页规则 while url: # 获取网页文本内容 html = get_html(url) if not html: break # 获取关键信息 data = get_data(html) # 写入文件 file_name = '中文日报.csv' save_data(data, file_name) # 解析HTML文本,查找下一页链接 bs = BeautifulSoup(html,'lxml') next_page_tag = bs.find('a',text='下一页') if next_page_tag: url = 'https:' + next_page_tag.get('href') else: url = None
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]