用Python实现简单定时爬虫:每日自动抓取和保存数据

1,358 阅读3分钟

这周开发中有个需求,每日固定时间爬取数据,保持csv文件到本地,在此记录下定时爬取的过程,后续会优化存在数据库中,每日定时存储。

image.png

背景介绍

我们使用 Python 的 schedule 库来实现定时任务,并利用 requests 库来抓取网页数据。我们要抓取的网站每天会更新一些特定类型的数据,我们希望能够定时地抓取这些数据并保存下来,以便日后分析。

环境准备

首先,我们需要安装一些必要的 Python 库:

pip install requests schedule

1. 抓取数据

我们使用 requests 库发送 GET 请求来抓取网页数据,并返回原始的响应数据:

import requests

def fetch_data(url):
    response = requests.get(url)
    data = response.text
    return data

2. 保存数据

我们将解析后的数据保存为 CSV 文件。

import csv

def save_to_csv(data, filename):
    if not data:
        print(f"No data to save for {filename}")
        return

    keys = data[0].keys()
    with open(filename, 'w', newline='') as csvfile:
        csvwriter = csv.DictWriter(csvfile, fieldnames=keys)
        csvwriter.writeheader()
        csvwriter.writerows(data)

3. 定时任务

我们使用 schedule 库来设置定时任务。以下是完整的定时任务函数:

from datetime import datetime, timedelta
import schedule

def job():
    date_str = datetime.now().strftime('%Y-%m-%d')
    
    market_types = ["001", "003", "N"]
    
    for market_type in market_types:
        page_number = 1
        all_data = []

        while True:
            url = (f"...")

            raw_data = fetch_data(url)
            json_data = parse_data(raw_data)
            
            if json_data.get('code') != 0:
                print(f"Error fetching data for market type {market_type} on page {page_number}")
                break
            
            result = json_data.get('result', {})
            data = result.get('data', [])
            all_data.extend(data)
            
            pages = result.get('pages', 1)
            if page_number >= pages:
                break
            
            page_number += 1

        filename = f"data_market_{market_type}_{date_str}.csv"
        save_to_csv(all_data, filename)
        print(f"Saved data to {filename}")

我们将每天早上8点52分执行这个任务:

schedule.every().day.at("08:52").do(job)
while True:
    schedule.run_pending()
    time.sleep(1)

schedule 库简介

schedule 是一个用于调度任务的轻量级 Python 库。它允许你用简单的语法来设置定时任务,非常适合处理需要周期性执行的任务,如每天定时抓取数据、定时备份文件等。 schedule 的用法非常简单直观。以下是一些常用的调度任务示例:

1. 安排每天执行的任务
import schedule
import time

def job():
    print("Task executed!")

# 每天某个时间执行一次任务
schedule.every().day.at("10:30").do(job)

while True:
    schedule.run_pending()
    time.sleep(1)
2. 安排每小时执行的任务
import schedule
import time

def job():
    print("Task executed!")

# 每小时执行一次任务
schedule.every().hour.do(job)

while True:
    schedule.run_pending()
    time.sleep(1)
3. 安排每周某天执行的任务
import schedule
import time

def job():
    print("Task executed!")

# 每周一的10:30执行任务
schedule.every().monday.at("10:30").do(job)

while True:
    schedule.run_pending()
    time.sleep(1)
4. 安排每隔一定时间执行的任务
import schedule
import time

def job():
    print("Task executed!")

# 每5分钟执行一次任务
schedule.every(5).minutes.do(job)

while True:
    schedule.run_pending()
    time.sleep(1)

完整代码

以下是完整的代码实现,供大家参考:

import requests
import random
import time
import schedule
import csv
from datetime import datetime, timedelta
import json


def fetch_data(url):
    response = requests.get(url)
    data = response.text
    return data


def save_to_csv(data, filename):
    if not data:
        print(f"No data to save for {filename}")
        return

    keys = data[0].keys()
    with open(filename, 'w', newline='') as csvfile:
        csvwriter = csv.DictWriter(csvfile, fieldnames=keys)
        csvwriter.writeheader()
        csvwriter.writerows(data)

def job():
    date_str = datetime.now().strftime('%Y-%m-%d')  
    market_types = ["001", "003", "N"]
    
    for market_type in market_types:
        page_number = 1
        all_data = []

        while True:
            # 这里隐藏了具体的 URL 拼接部分
            url = (f"...")

            raw_data = fetch_data(url)
            json_data = parse_data(raw_data)
            
            if json_data.get('code') != 0:
                print(f"Error fetching data for market type {market_type} on page {page_number}")
                break
            
            result = json_data.get('result', {})
            data = result.get('data', [])
            all_data.extend(data)
            
            pages = result.get('pages', 1)
            if page_number >= pages:
                break
            
            page_number += 1

        filename = f"data_market_{market_type}_{date_str}.csv"
        save_to_csv(all_data, filename)
        print(f"Saved data to {filename}")

# 定时每天早上8点执行爬取任务
schedule.every().day.at("08:00").do(job)

while True:
    schedule.run_pending()
    time.sleep(1)

总结

通过上述步骤,我们实现了一个简单而有效的定时爬虫。这个爬虫每天会自动抓取指定网站的数据,并保存为 CSV 文件。这样我们就可以方便地进行后续的数据分析工作了。