首页 > 编程语言 >Python爬虫技术 第32节 最佳实践和常见问题

Python爬虫技术 第32节 最佳实践和常见问题

时间:2024-08-04 09:26:36浏览次数:10  
标签:articles 常见问题 logging Python 32 爬虫 url html fetch

Python爬虫技术是一种用于从网站上自动抓取数据的技术。它涉及到网络请求、HTML解析、数据提取等多个环节。下面我将详细介绍Python爬虫的最佳实践以及一些常见的问题解决方法,包括日志记录和错误报告、爬虫维护和更新等方面。

Python爬虫基础架构

一个典型的Python爬虫程序通常包含以下几个部分:

  1. 请求模块:负责发送HTTP请求获取网页内容。
  2. 解析模块:对获取到的HTML内容进行解析,提取所需数据。
  3. 存储模块:将提取的数据保存到本地文件、数据库或其他存储系统中。
  4. 控制模块:管理整个爬虫的运行流程,包括任务调度、异常处理等。

Python爬虫最佳实践

1. 遵守Robots协议
  • 在爬取之前,检查目标网站的robots.txt文件,确保你的爬虫行为符合网站的政策。
  • 使用urllib.robotparser库来读取和解析robots.txt文件。
2. 用户代理设置
  • 使用合理的User-Agent来模拟浏览器访问,避免被服务器识别为爬虫而被封禁。
  • 可以随机更换User-Agent来降低被检测的风险。
3. 请求频率控制
  • 控制请求间隔时间,避免给目标服务器带来过大负担。
  • 使用time.sleep()函数来延迟请求,或者使用更高级的库如scrapy来自动处理延迟。
4. 错误处理
  • 对HTTP请求设置超时时间。
  • 捕获异常并进行适当的错误处理,例如重试机制。
5. 数据持久化
  • 使用合适的数据库存储数据,如SQLite、MySQL等。
  • 考虑数据的结构化存储,比如使用CSV或JSON格式。

日志记录和错误报告

日志记录
  • 使用Python内置的logging模块来记录爬虫的运行状态。
  • 设置不同的日志级别,如DEBUG、INFO、WARNING、ERROR、CRITICAL。
  • 将日志输出到文件,便于后期分析和审计。
错误报告
  • 当出现错误时,通过电子邮件或其他通知方式发送错误报告。
  • 可以利用第三方服务如Sentry、Loggly等进行错误追踪和管理。

爬虫维护和更新

维护
  • 定期检查目标网站的布局变化,更新解析规则。
  • 监控爬虫性能和效率,及时发现并解决问题。
更新
  • 使用版本控制系统(如Git)来管理爬虫代码。
  • 创建自动化测试来确保代码修改后仍能正常工作。

示例代码

这里给出一个简单的Python爬虫框架示例:

import requests
from bs4 import BeautifulSoup
import logging
import time

# 配置日志
logging.basicConfig(filename='spider.log', level=logging.INFO,
                    format='%(asctime)s:%(levelname)s:%(message)s')

def fetch_url(url):
    try:
        response = requests.get(url, headers={'User-Agent': 'Mozilla/5.0'})
        response.raise_for_status()
        return response.text
    except requests.RequestException as e:
        logging.error(f"Failed to fetch {url}: {e}")
        return None

def parse_html(html):
    soup = BeautifulSoup(html, 'html.parser')
    # 假设我们要提取所有文章标题
    titles = [title.get_text() for title in soup.find_all('h2')]
    return titles

def main():
    url = 'https://example.com'
    html = fetch_url(url)
    if html:
        titles = parse_html(html)
        print(titles)
        logging.info("Successfully fetched and parsed the data.")
    else:
        logging.warning("Failed to fetch or parse the data.")

if __name__ == "__main__":
    main()

常见问题及解决方案

  1. 被目标网站封锁

    • 更换IP地址或使用代理服务器。
    • 减少请求频率。
  2. 页面布局改变导致解析出错

    • 定期检查目标网站的HTML结构,并相应地更新解析规则。
  3. 数据存储问题

    • 选择合适的数据存储方案,如使用关系型数据库或NoSQL数据库。
    • 设计合理的数据模型。

通过遵循以上最佳实践和解决方案,你可以构建出更加健壮和高效的Python爬虫程序。如果有更具体的场景或问题,请随时告知,我会提供更详细的指导。

下面我们将基于之前的示例代码进一步扩展,增加更多的功能和细节,以构建一个更完整的Python爬虫程序。这次我们将添加日志记录、错误处理、以及爬虫维护和更新方面的功能。

示例代码

假设我们的目标是从一个新闻网站上抓取最新的文章标题和链接。我们将使用requests库来发送HTTP请求,并使用BeautifulSoup库来解析HTML文档。

import requests
from bs4 import BeautifulSoup
import logging
import time
import os

# 配置日志
logging.basicConfig(filename='spider.log', level=logging.INFO,
                    format='%(asctime)s:%(levelname)s:%(message)s')

# 用户代理列表
USER_AGENTS = [
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.106 Safari/537.36",
    "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36",
]

def get_random_user_agent():
    """返回随机的用户代理"""
    return USER_AGENTS[random.randint(0, len(USER_AGENTS) - 1)]

def fetch_url(url, timeout=10, retries=3):
    """发送HTTP请求并返回响应文本"""
    headers = {'User-Agent': get_random_user_agent()}
    try:
        response = requests.get(url, headers=headers, timeout=timeout)
        response.raise_for_status()
        return response.text
    except requests.RequestException as e:
        logging.error(f"Failed to fetch {url}: {e}")
        if retries > 0:
            logging.info(f"Retrying fetching {url} ({retries} retries left)")
            time.sleep(5)  # 等待5秒后重试
            return fetch_url(url, timeout, retries - 1)
        else:
            return None

def parse_html(html):
    """解析HTML文档并提取文章标题和链接"""
    soup = BeautifulSoup(html, 'html.parser')
    articles = []
    for article in soup.find_all('article'):
        title = article.find('h2').get_text().strip()
        link = article.find('a')['href']
        articles.append({'title': title, 'link': link})
    return articles

def save_articles(articles):
    """保存文章到本地文件"""
    timestamp = time.strftime("%Y%m%d-%H%M%S")
    filename = f"articles_{timestamp}.json"
    with open(filename, 'w') as file:
        json.dump(articles, file, indent=2)

def main():
    url = 'https://example.com/news'
    html = fetch_url(url)
    if html:
        articles = parse_html(html)
        save_articles(articles)
        logging.info("Successfully fetched and parsed the data.")
    else:
        logging.warning("Failed to fetch or parse the data.")

if __name__ == "__main__":
    main()

代码解释

  1. 日志记录和错误处理

    • 使用logging模块记录爬虫的日志。
    • fetch_url函数中,增加了重试机制来处理网络请求中的异常。
  2. 数据提取

    • parse_html函数中,使用BeautifulSoup解析HTML文档并提取文章标题和链接。
  3. 数据存储

    • save_articles函数中,将提取的文章数据保存到本地JSON文件中。
  4. 用户代理

    • 使用了一个用户代理列表,并在每次请求时随机选择一个用户代理。
  5. 错误处理

    • fetch_url函数中,通过设置重试次数和等待时间来处理网络请求失败的情况。

扩展功能

接下来,我们可以考虑添加更多功能来进一步完善爬虫程序:

  1. 多线程或异步请求

    • 使用concurrent.futuresasyncio来并发处理多个请求,加快爬取速度。
  2. 代理服务器

    • 使用代理服务器来避免被目标网站封禁。
  3. 更复杂的解析逻辑

    • 根据目标网站的具体结构,可能需要更复杂的解析逻辑来提取数据。
  4. 自动化部署

    • 结合前面提到的CI/CD流程,实现爬虫的自动化部署。
  5. 监控和报警

    • 使用监控工具(如Prometheus、Grafana)来监控爬虫的运行状态,并在出现异常时发送报警。

通过不断地扩展和完善,你可以构建出一个功能强大且稳定的爬虫程序。如果你有更具体的场景或需求,请随时告诉我,我会提供更多帮助。

现在我们将进一步扩展之前的Python爬虫示例,添加多线程处理能力以提高爬虫的效率,并实现更细致的日志记录和错误处理机制。此外,我们还将探讨如何维护和更新爬虫以适应网站的变化。

示例代码

为了实现多线程处理,我们将使用Python标准库中的concurrent.futures模块。这样可以并行地处理多个URL请求,从而加快爬虫的速度。

import requests
from bs4 import BeautifulSoup
import logging
import time
import os
import random
import json
from concurrent.futures import ThreadPoolExecutor

# 配置日志
logging.basicConfig(filename='spider.log', level=logging.INFO,
                    format='%(asctime)s:%(levelname)s:%(message)s')

# 用户代理列表
USER_AGENTS = [
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.106 Safari/537.36",
    "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36",
]

def get_random_user_agent():
    """返回随机的用户代理"""
    return USER_AGENTS[random.randint(0, len(USER_AGENTS) - 1)]

def fetch_url(url, timeout=10, retries=3):
    """发送HTTP请求并返回响应文本"""
    headers = {'User-Agent': get_random_user_agent()}
    try:
        response = requests.get(url, headers=headers, timeout=timeout)
        response.raise_for_status()
        return response.text
    except requests.RequestException as e:
        logging.error(f"Failed to fetch {url}: {e}")
        if retries > 0:
            logging.info(f"Retrying fetching {url} ({retries} retries left)")
            time.sleep(5)  # 等待5秒后重试
            return fetch_url(url, timeout, retries - 1)
        else:
            return None

def parse_html(html):
    """解析HTML文档并提取文章标题和链接"""
    soup = BeautifulSoup(html, 'html.parser')
    articles = []
    for article in soup.find_all('article'):
        title = article.find('h2').get_text().strip()
        link = article.find('a')['href']
        articles.append({'title': title, 'link': link})
    return articles

def save_articles(articles):
    """保存文章到本地文件"""
    timestamp = time.strftime("%Y%m%d-%H%M%S")
    filename = f"articles_{timestamp}.json"
    with open(filename, 'w') as file:
        json.dump(articles, file, indent=2)

def fetch_and_parse(url):
    """并行地执行获取和解析操作"""
    html = fetch_url(url)
    if html:
        articles = parse_html(html)
        return articles
    else:
        return []

def main():
    urls = ['https://example.com/news', 'https://example.com/articles']  # 假设有两个URL需要爬取
    max_workers = 2  # 设置最大并发数
    
    with ThreadPoolExecutor(max_workers=max_workers) as executor:
        future_to_url = {executor.submit(fetch_and_parse, url): url for url in urls}
        for future in future_to_url:
            url = future_to_url[future]
            try:
                articles = future.result()
                save_articles(articles)
                logging.info(f"Successfully fetched and parsed data from {url}.")
            except Exception as exc:
                logging.error(f"Failed to fetch or parse data from {url}: {exc}")

if __name__ == "__main__":
    main()

代码解释

  1. 多线程处理

    • 使用ThreadPoolExecutor来并行处理多个URL请求。
    • future_to_url字典用于跟踪每个Future对象对应的URL。
  2. 日志记录

    • 记录成功的请求和解析结果,同时也记录失败的情况。
  3. 错误处理

    • main函数中使用try-except块来捕获并记录任何未预期的异常。

爬虫维护和更新

维护和更新爬虫是非常重要的,因为网站可能会经常发生变化,这可能会影响到爬虫的正常运行。以下是一些建议:

  1. 定期检查目标网站

    • 定期检查目标网站的布局是否发生了变化。
    • 使用自动化测试来确保爬虫仍然能够正确地提取数据。
  2. 使用版本控制

    • 使用Git或其他版本控制系统来管理你的爬虫代码。
    • 每次修改代码时都进行提交,并附上描述性的提交信息。
  3. 自动化测试

    • 编写自动化测试来验证爬虫的功能。
    • 可以使用pytest或其他测试框架来编写单元测试。
  4. 监控爬虫性能

    • 使用日志文件来监控爬虫的运行情况。
    • 可以设置警报系统,当爬虫遇到问题时自动发送通知。
  5. 备份数据

    • 定期备份爬虫收集的数据,以防数据丢失。
  6. 文档记录

    • 保持良好的文档记录,包括爬虫的设计、功能、使用说明等。

通过以上的方法,你可以构建一个既高效又可靠的Python爬虫,并确保它能够长期稳定运行。如果你有更具体的场景或需求,请随时告诉我,我会提供更多帮助。

标签:articles,常见问题,logging,Python,32,爬虫,url,html,fetch
From: https://blog.csdn.net/hummhumm/article/details/140886962

相关文章

  • 机器学习:Python还是R,哪个更好?
    在机器学习领域,选择合适的编程语言是成功的关键因素之一。Python和R是最受欢迎的两种编程语言,各自具有独特的优势和应用场景。本文将探讨Python和R在机器学习中的优缺点,帮助你决定哪种语言更适合你的需求。一、Python和R概述PythonPython是一种通用的编程语言,以其简洁的语法......
  • 初级python代码编程学习----简单计算器代码学习 入门必看
    简单计算器的代码今天来点最简单的python代码。让有兴趣的网友可以快速尝试入门。 defadd(x,y):returnx+ydefsubtract(x,y):returnx-ydefmultiply(x,y):returnx*ydefdivide(x,y):ify==0:return"Error!Divisionb......
  • Python | ValueError: invalid literal for int() with base 10: ‘example’
    Python|ValueError:invalidliteralforint()withbase10:‘example’在Python编程中,遇到ValueError:invalidliteralforint()withbase10:'example'这样的错误通常意味着你试图将一个字符串转换为整数,但该字符串包含非数字字符。这种错误常见于数据输入、文......
  • Python函数的异常
    #异常:是一个事件,这个时间在程序执行过程中发生,影响了程序的正常执行#异常处理最终目的:让程序在有异常时,仍能够正常运行#语法格式一:try:  print(a)  #可能够引发异常的现象的代码except:  #基类异常  print('出现错误')b=10print(b)#法二try: ......
  • Python爬虫技术 第31节 持续集成和自动化部署
    持续集成和自动化部署Git版本控制Git是一个非常流行的分布式版本控制系统,用于跟踪对项目文件的修改。对于爬虫项目来说,使用Git可以帮助你管理代码的不同版本,协同开发,并且可以在出现问题时回滚到之前的版本。基本操作:安装Git:在你的操作系统上安装Git。初始化仓库:使用......
  • STM32卡死、跑飞如何调试确定问题
    目录前言一、程序跑飞原因二、调试工具2.1Registers工具2.2Memory工具2.3 Disassembly工具2.4 CallStack工具三、找到程序跑飞位置方式一、方式二、前言我们初学STM32的时候代码难免会出现疏忽,导致程序跑飞,不再正常运行,那么都是什么情况会导致STM32程序跑飞......
  • IPython的使用技巧2
    关注我,持续分享逻辑思维&管理思维&面试题;可提供大厂面试辅导、及定制化求职/在职/管理/架构辅导;推荐专栏《10天学会使用asp.net编程AI大模型》,目前已完成所有内容。一顿烧烤不到的费用,让人能紧跟时代的浪潮。从普通网站,到公众号、小程序,再到AI大模型网站。干货满满。学成后可......
  • Python学习笔记51:暂停篇
    随便写点最近因为公司项目的原因,学习进度变慢很多,但是也勉强支撑着把小游戏的项目写了个大概,其实后续很多的功能基本都是慢慢添加就可以,掌握了函数的调用,磕磕碰碰终究还是能把功能写好的,可能就是代码质量差一点,但是这个没必要过于纠结,写的多了看的多了,慢慢的就会进步。一......
  • python pip怎么用
    pip是Python包管理工具,该工具提供了对Python包的查找、下载、安装、卸载的功能。目前如果你在python.org下载最新版本的安装包,则是已经自带了该工具。Python2.7.9+或Python3.4+以上版本都自带pip工具。pip官网:https://pypi.org/project/pip/你可以通过以......
  • python pip怎么安装包
    按Win+R键打开运行窗口,输入“cmd”,再按回车键,打开命令行窗口。找到pip安装路径。Python2/Python3安装路径是相同的,都在x:\Pythonxx\Scripts路径下。拖动pip主应用程序到命令行窗口。输入“install+模块/包名”,注意中间要有空格。然后按回车键,窗口中会显示......