万万哇 发表于 2025-3-22 01:49:06

爬虫入门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]
查看完整版本: 爬虫入门re+bs4