Python星球日记 - 第16天:爬虫基础(仅学习使用)

🌟引言

上一篇:Python星球日记 - 第15天:综合复习(回顾前14天所学知识)
名人说:不要人夸颜色好,只留清气满乾坤(王冕《墨梅》)
创作者:Code_流苏(CSDN) (一个喜欢古诗词和编程的Coder😊)

目录

    • 一、爬虫的概念与原理
      • [1. 什么是网络爬虫](#1. 什么是网络爬虫)
      • [2. 爬虫的工作原理](#2. 爬虫的工作原理)
      • [3. 爬虫的法律和道德考量⚠️](#3. 爬虫的法律和道德考量⚠️)
    • [二、使用 requests 库获取网页数据](#二、使用 requests 库获取网页数据)
      • [1. `requests`库介绍](#1. requests库介绍)
      • [2. 发送GET请求](#2. 发送GET请求)
      • [3. 处理响应内容](#3. 处理响应内容)
      • [4. 设置请求头和参数](#4. 设置请求头和参数)
    • [三、使用 BeautifulSoup 解析HTML](#三、使用 BeautifulSoup 解析HTML)
      • [1. BeautifulSoup简介](#1. BeautifulSoup简介)
      • [2. 安装和导入](#2. 安装和导入)
      • [3. 解析HTML文档](#3. 解析HTML文档)
      • [4. 选择和提取元素](#4. 选择和提取元素)
    • 四、实战练习:爬取网站标题列表
      • [1. 目标分析](#1. 目标分析)
      • [2. 编写爬虫代码](#2. 编写爬虫代码)
      • [3. 运行和结果分析](#3. 运行和结果分析)
      • [4. 优化和扩展](#4. 优化和扩展)
    • 五、练习(仅学习用途)
    • 六、总结
    • 参考资源

专栏介绍: Python星球日记专栏介绍(持续更新ing)
更多Python知识,请关注我、订阅专栏《 Python星球日记》,内容持续更新中...

欢迎来到Python星球🪐的第16天!

在学习完Python基础知识并进行了复习后,我们今天将探索一个非常实用的Python应用领域:网络爬虫 。通过今天的学习,你将了解如何使用Python抓取互联网上的数据,这是数据分析、人工智能和自动化任务的重要基础。

一、爬虫的概念与原理

1. 什么是网络爬虫

网络爬虫 (Web Crawler)是一种自动获取网页内容的程序。它可以访问互联网上的网页,获取其中的数据,并根据需要进行分析和存储。爬虫就像是我们派出去的"数字蜘蛛 ",它们在互联网的"网络"上爬行,收集我们需要的信息。

2. 爬虫的工作原理

爬虫的基本工作原理可以概括为以下几个步骤:

  1. 发送请求 :爬虫向目标网站发送HTTP请求,就像我们在浏览器中输入网址一样。
  2. 获取响应 :服务器返回响应,通常包含HTML、JSON或其他格式的数据。
  3. 解析数据 :爬虫解析获取到的数据,提取出需要的信息。
  4. 数据处理 :对提取的数据进行清洗、转换和存储
  5. 应用数据 :将处理后的数据用于分析、展示或其他用途。

3. 爬虫的法律和道德考量⚠️

在进行网络爬虫活动时,我们需要注意以下几点🌟

  • 尊重robots.txt :许多网站都有一个名为robots.txt的文件,用于告诉爬虫哪些页面可以访问,哪些不能。
  • 控制请求频率 :过于频繁的请求可能会给服务器带来负担,甚至被误认为是DoS攻击(拒绝服务攻击)。
  • 遵守法律法规:不要爬取受版权保护的内容或个人隐私数据。
  • 注意使用条款:某些网站在使用条款中明确禁止爬虫活动。

二、使用 requests 库获取网页数据

1. requests库介绍

requests是Python中最受欢迎的 HTTP客户端库 ,它使得发送HTTP请求变得简单而直观。该库的设计理念是"为人类准备的HTTP库",因此使用起来非常友好。

首先,我们需要安装requests库:

python 复制代码
pip install requests

2. 发送GET请求

使用requests库发送GET请求非常简单:

python 复制代码
import requests

# 发送GET请求
response = requests.get('https://www.example.com')

# 检查请求是否成功
if response.status_code == 200:
    print('请求成功!')
else:
    print(f'请求失败,状态码: {response.status_code}')

例如,访问 www.baidu.com,向百度搜索主页发送GET请求

python 复制代码
import requests

# 发送GET请求
response = requests.get('https://www.baidu.com')

# 检查请求是否成功
if response.status_code == 200:
    print('请求成功!')
else:
    print(f'请求失败,状态码: {response.status_code}')

可以看到,"请求成功!",说明我们向百度搜索主页发送成功了请求。

3. 处理响应内容

成功发送请求后,我们可以通过多种方式访问响应内容

python 复制代码
import requests

response = requests.get('https://www.example.com')

# 获取响应文本
html_content = response.text

# 获取二进制内容(如图片)
binary_content = response.content

# 如果响应是JSON格式,可以直接获取JSON数据
if 'application/json' in response.headers.get('Content-Type', ''):
    json_data = response.json()
    print(json_data)

例如,访问 www.baidu.com,向百度获取响应文本

python 复制代码
import requests

response = requests.get('https://www.baidu.com')

# 检查请求是否成功
if response.status_code == 200:
    print('请求成功!')
else:
    print(f'请求失败,状态码: {response.status_code}')

# 获取响应文本
html_content = response.text

# 获取二进制内容(如图片)
binary_content = response.content

# 如果响应是JSON格式,可以直接获取JSON数据
if 'application/json' in response.headers.get('Content-Type', ''):
    json_data = response.json()
    print(json_data)

可以看到,"请求成功!",说明我们向百度搜索主页发送成功了请求,但没有显示JSON数据,这说明中间存在某种机制在阻挡着。

这种机制是 反爬虫措施,会拒绝不像普通浏览器的请求。

那为什么会出现这个问题? 可能是因为:

  1. 缺少浏览器标识:网站可以检测到您的请求不是来自常规浏览器
  2. 反爬虫机制:大型网站如百度有复杂的反爬虫系统
  3. 重定向处理:网站可能将您重定向到其他页面而不直接返回内容

该怎么解决呢?我们可以设置一下请求头事实。

4. 设置请求头和参数

有时我们需要自定义请求头或传递参数:

python 复制代码
import requests

# 设置请求头,模拟真实浏览器
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',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
    'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
    'Connection': 'keep-alive'
}

try:
    # 发送带有浏览器标识的请求
    response = requests.get('https://www.baidu.com', headers=headers, timeout=10)
    
    # 检查请求是否成功
    print(f'状态码: {response.status_code}')
    
    # 查看请求是否被重定向
    if response.history:
        print(f'请求被重定向了 {len(response.history)} 次')
        print(f'最终URL: {response.url}')
    
    # 获取部分响应头信息
    print(f'内容类型: {response.headers.get("Content-Type", "未知")}')
    print(f'内容长度: {response.headers.get("Content-Length", "未知")}')
    
    # 检查内容
    if response.text:
        print(f'响应长度: {len(response.text)} 字符')
        print('前100个字符预览:')
        print(response.text[:100])
    else:
        print('没有获取到文本内容')
        
    # 检查是否有内容编码可能影响解析
    if response.encoding:
        print(f'内容编码: {response.encoding}')
        
    # 显示所有cookies
    print('Cookies:')
    for cookie in response.cookies:
        print(f'  {cookie.name}: {cookie.value}')
        
except requests.exceptions.RequestException as e:
    print(f'请求异常: {e}')

之后我们就能看到获取到的响应内容了。

三、使用 BeautifulSoup 解析HTML

1. BeautifulSoup简介

BeautifulSoup是一个强大的 HTML和XML解析库 ,它可以将HTML文档转换成树形结构,方便我们提取需要的信息。

2. 安装和导入

首先,我们需要安装 BeautifulSoup 库和一个解析器(这里使用lxml):

python 复制代码
pip install beautifulsoup4 lxml

然后在代码中导入:

python 复制代码
import requests
from bs4 import BeautifulSoup

3. 解析HTML文档

获取网页内容后,我们可以使用 BeautifulSoup 进行解析:

python 复制代码
import requests
from bs4 import BeautifulSoup

# 获取网页内容
response = requests.get('https://www.example.com')
html_content = response.text

# 创建BeautifulSoup对象
soup = BeautifulSoup(html_content, 'html.parser')

# 打印格式化后的HTML
print(soup.prettify())

同样地 ,访问 www.baidu.com,我们借助 BeautifulSoup 来解析HTML文档

python 复制代码
import requests
from bs4 import BeautifulSoup

# 获取网页内容
response = requests.get('https://www.baidu.com')
html_content = response.text

# 使用内置的 html.parser
soup = BeautifulSoup(html_content, 'html.parser')

# 打印格式化后的HTML
print(soup.prettify())

可以看到,终端处已经出现了格式化后的HTML

补充一点:解析器选择建议

对于网络爬虫和大多数 Web 开发工作:

  • 如果性能和准确性是优先事项,安装并使用 lxml
  • 如果只是简单脚本或不想有外部依赖,使用内置的 html.parser
  • 如果需要处理非常复杂或格式不规范的 HTML,考虑安装 html5lib

4. 选择和提取元素

BeautifulSoup提供了多种方法来选择和提取HTML元素:

python 复制代码
import requests
from bs4 import BeautifulSoup

# 设置请求头,模拟浏览器
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'
}

try:
    # 发送请求获取网页内容
    response = requests.get('https://www.baidu.com', headers=headers)
    
    # 检查请求是否成功
    if response.status_code == 200:
        # 打印响应内容的前100个字符,帮助诊断
        print("响应内容预览: ", response.text[:100])
        
        # 解析HTML
        soup = BeautifulSoup(response.text, 'lxml')
        
        # 安全地获取元素 - 方法一:使用条件判断
        if soup.title:
            title_text = soup.title.text
            print(f"网页标题: {title_text}")
        else:
            print("网页中没有找到<title>标签")
        
        # 安全地获取元素 - 方法二:使用.get()方法获取属性
        first_paragraph = soup.find('p')
        if first_paragraph:
            paragraph_text = first_paragraph.text
            print(f"第一个段落: {paragraph_text}")
        else:
            print("网页中没有找到<p>标签")
        
        # 安全地获取元素 - 方法三:使用try-except捕获可能的错误
        try:
            first_link = soup.find('a')
            if first_link:
                link_href = first_link.get('href', '无链接')  # 使用get方法提供默认值
                print(f"第一个链接: {link_href}")
            else:
                print("网页中没有找到<a>标签")
        except Exception as e:
            print(f"处理链接时出错: {e}")
            
        # 方法四:链式调用与默认值结合
        content_div_text = soup.select_one('div.content').text if soup.select_one('div.content') else "未找到内容区块"
        print(f"内容区块: {content_div_text}")
    else:
        print(f"请求失败,状态码: {response.status_code}")
        
except Exception as e:
    print(f"程序执行出错: {e}")

访问 www.baidu.com,我们来选择和提取元素,可以看到,我们已经提取到了我们要找的元素。

四、实战练习:爬取网站标题列表

现在,让我们将学到的知识应用到实际案例中:爬取CSDN首页的文章标题列表。

1. 目标分析

我们的目标是爬取百度新闻首页https://news.baidu.com/)的文章标题。在开始编写代码前,我们可以通过浏览器的开发者工具检查页面结构,找出包含标题的HTML元素。

2. 编写爬虫代码

python 复制代码
import requests
from bs4 import BeautifulSoup
import time

# 设置请求头,模拟浏览器访问
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'
}

# 发送请求获取百度新闻页面的内容
url = 'https://news.baidu.com/'
response = requests.get(url, headers=headers)

# 检查请求是否成功
if response.status_code == 200:
    # 使用BeautifulSoup解析HTML
    soup = BeautifulSoup(response.text, 'lxml')
    
    # 查找所有文章标题元素
    # 注意:以下选择器可能需要根据实际网页结构调整
    title_elements = soup.select('a.title')
    
    # 提取并打印标题
    print(f"共找到 {len(title_elements)} 篇文章")
    for i, title in enumerate(title_elements, 1):
        print(f"{i}. {title.text.strip()}")
        
        # 适当延时,避免请求过快
        if i % 5 == 0 and i < len(title_elements):
            time.sleep(0.5)
else:
    print(f"请求失败,状态码: {response.status_code}")

我们可以看到,并没有获取到百度新闻的文章列表,此时我们需要考虑其它方案来解决。

3. 运行和结果分析

运行上面的代码,你应该能看到百度新闻页面的文章标题列表。如果遇到问题,可能是因为网站结构发生了变化,需要调整选择器。

4. 优化和扩展

我们可以对代码进行一些优化和扩展:

python 复制代码
import requests
from bs4 import BeautifulSoup
import csv

def crawl_with_requests():
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
        'Accept-Language': 'zh-CN,zh;q=0.9'
    }
    
    try:
        # 尝试访问本地或国内网站,可能更容易成功
        url = 'https://news.baidu.com/'  # 例如使用百度新闻
        response = requests.get(url, headers=headers, timeout=20)
        response.raise_for_status()
        
        soup = BeautifulSoup(response.text, 'html.parser')
        
        # 获取新闻标题
        articles = []
        news_links = soup.select('.hotnews a, .ulist a')
        
        for link in news_links:
            title = link.text.strip()
            href = link.get('href', '')
            if title and href and len(title) > 5:
                articles.append({
                    'title': title,
                    'link': href
                })
        
        # 保存结果
        with open('news_titles.csv', 'w', encoding='utf-8', newline='') as f:
            writer = csv.DictWriter(f, fieldnames=['title', 'link'])
            writer.writeheader()
            writer.writerows(articles)
            
        print(f"成功爬取 {len(articles)} 条新闻标题,已保存到 news_titles.csv")
        
    except Exception as e:
        print(f"发生错误: {e}")
        import traceback
        traceback.print_exc()

if __name__ == "__main__":
    crawl_with_requests()

这个优化版本增加了:

  • 异常处理:捕获各种可能的异常
  • 超时设置:防止请求长时间等待
  • 数据存储:将结果保存为CSV文件
  • 功能封装:将爬虫代码封装为函数

五、练习(仅学习用途)

  1. 修改本文提供的代码,爬取你喜欢的技术博客网站的文章标题和发布日期。
  2. 尝试使用requestsBeautifulSoup爬取一个简单的图片网站,并将图片保存到本地。
  3. 研究CSDN的robots.txt文件,了解该网站对爬虫的规定。
  4. 思考:如何爬取需要登录才能访问的网页内容?

六、总结

今天,我们学习了网络爬虫 的基本概念和原理,掌握了使用requests库获取网页数据和BeautifulSoup解析HTML的方法。通过实战练习,我们成功爬取了百度新闻的文章标题列表。

爬虫的知识还有很多,本篇仅入门了解,详细地大家可以查看官方文档使用,谢谢理解。

网络爬虫是一个强大的工具,它可以帮助我们自动化数据收集过程,为数据分析和机器学习提供原材料。然而,我们也要记住,务必注意!!!使用爬虫时需要遵守法律法规和网站的使用条款,尊重数据提供者的权益!

在接下来的学习中,我们将深入探索更多方向的基础知识,敬请期待《Python星球日记》的后续内容!

参考资源

  1. requests官方文档:https://requests.readthedocs.io/
  2. BeautifulSoup官方文档:https://www.crummy.com/software/BeautifulSoup/bs4/doc/
  3. 《Python网络数据采集》------ Ryan Mitchell 著
  4. 网络爬虫与信息提取:https://www.icourse163.org/course/BIT-1001870001

祝你在Python爬虫的旅程中收获满满!

创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊)

如果你对今天的内容有任何问题,或者想分享你的学习心得,欢迎在评论区留言讨论!

相关推荐
小白教程2 天前
Python爬取视频的架构方案,Python视频爬取入门教程
python·架构·音视频·python爬虫·python视频爬虫·python爬取视频教程
攻城狮7号2 天前
Python爬虫第13节-解析库pyquery 的使用
爬虫·python·python爬虫
攻城狮7号3 天前
Python爬虫第9节-爬取猫眼电影排行数据的简单实战
爬虫·python·python爬虫
攻城狮7号5 天前
Python爬虫第7节-requests库的高级用法
python·python爬虫
攻城狮7号6 天前
Python爬虫第5节-urllib的异常处理、链接解析及 Robots 协议分析
爬虫·python·python爬虫
唐叔在学习8 天前
【Python爬虫高级技巧】BeautifulSoup高级教程:数据抓取、性能调优、反爬策略,全方位提升爬虫技能!
python·beautifulsoup·html解析·爬虫进阶·反爬策略
攻城狮7号11 天前
Python爬虫第2节-网页基础和爬虫基本原理
爬虫·python爬虫
攻城狮7号12 天前
【第一节】Python爬虫基础-HTTP基本原理
爬虫·python·python爬虫
熊文豪12 天前
XPath语法完全指南(实战详解版)
自动化测试·xpath·网页爬虫·数据提取·零基础入门·html解析·xpath教程