闲来无事,写个脚本爬一下快递信息

news/2024/11/29 4:06:39/
  1. 多线程爬取:可以使用Python中的多线程或异步IO技术来加速爬取速度,提高效率。
  2. 自动识别快递公司:可以通过输入的快递单号自动识别快递公司,然后根据不同公司的网站结构来爬取相应的信息。
  3. 数据存储:可以将爬取的数据存储到数据库或者文件中,方便后续的分析和使用。
  4. 可视化展示:可以使用Python中的数据可视化库,将爬取的数据可视化展示出来,方便用户查看和分析。
  5. 自动重试:可以在网络连接不稳定或者请求失败时自动重试,提高爬取成功率。
  6. 验证码识别:当出现验证码时,可以使用Python中的验证码识别库,自动识别验证码并输入,避免手动输入验证码的麻烦。
import requests
from bs4 import BeautifulSoup
import threading
import time
import random
import os
import re
import json
from PIL import Image
import pytesseract
import pymongo
import matplotlib.pyplot as plt# 定义线程数和线程锁
thread_num = 10
lock = threading.Lock()# 定义快递公司列表和快递公司匹配正则表达式
express_companies = {"shunfeng": {"name": "顺丰速运","regex": "^SF\d{12}$"},"yuantong": {"name": "圆通速递","regex": "^[A-Za-z0-9]{12}$"},"zhongtong": {"name": "中通快递","regex": "^[A-Za-z0-9]{12}$"},"yunda": {"name": "韵达快递","regex": "^120\d{11}$"}
}# 定义MongoDB客户端
client = pymongo.MongoClient("mongodb://localhost:27017/")
db = client["express"]
collection = db["tracking_info"]# 定义请求头
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36"
}# 定义验证码识别函数
def recognize_captcha(captcha_path):image = Image.open(captcha_path)captcha = pytesseract.image_to_string(image)captcha = re.sub(r"\W", "", captcha)return captcha# 定义爬取函数
def crawl(tracking_number):# 自动识别快递公司company = Nonefor key, value in express_companies.items():if re.match(value["regex"], tracking_number):company = keybreakif not company:print(f"未知快递公司,快递单号为:{tracking_number}")returnprint(f"开始爬取 {express_companies[company]['name']} 的快递信息,快递单号为:{tracking_number}")# 发送请求url = f"https://www.sf-express.com/sf-service-web/service/bills/{tracking_number}"response = requests.get(url, headers=headers)# 验证码识别if "验证码" in response.text:print(f"需要输入验证码,快递单号为:{tracking_number}")# 提取验证码图片链接soup = BeautifulSoup(response.text, "html.parser")captcha_url = soup.select_one(".captcha img")["src"]captcha_path = f"./captcha/{tracking_number}.png"# 下载验证码图片response = requests.get(captcha_url, headers=headers)with open(captcha_path, "wb") as f:f.write(response.content)# 识别验证码captcha = recognize_captcha(captcha_path)# 删除验证码图片os.remove(captcha_path)# 构造请求参数data = {"captcha": captcha,"billNo": tracking_number}response = requests.post(url, headers=headers, data=data)# 解析网页内容并保存到MongoDBsoup = BeautifulSoup(response.text, "html.parser")status_list = soup.select(".status-list li")tracking_info = []for status in status_list:date = status.select_one(".date").text.strip()time = status.select_one(".time").text.strip()location = status.select_one(".location").text.strip()status_desc = status.select_one(".status-desc").text.strip()tracking_info.append({"date": date,"time": time,"location": location,"status_desc": status_desc})data = {"tracking_number": tracking_number,"company": express_companies[company]["name"],"tracking_info": tracking_info}collection.insert_one(data)print(f"{tracking_number} 的快递信息已保存到MongoDB")# 可视化展示dates = [info["date"] for info in tracking_info]times = [info["time"] for info in tracking_info]status_descs = [info["status_desc"] for info in tracking_info]plt.plot(dates, status_descs)plt.title(f"{express_companies[company]['name']} 快递单号:{tracking_number}")plt.xlabel("日期")plt.ylabel("快递状态")plt.xticks(rotation=45)plt.show()# 定义线程函数
def thread_func(tracking_numbers):for tracking_number in tracking_numbers:crawl(tracking_number)time.sleep(random.randint(1, 3))# 主函数
if __name__ == "__main__":# 读取快递单号with open("tracking_numbers.txt", "r") as f:tracking_numbers = f.read().splitlines()# 分配任务给线程threads = []for i in range(thread_num):start = i * len(tracking_numbers) // thread_numend = (i + 1) * len(tracking_numbers) // thread_numthread = threading.Thread(target=thread_func, args=(tracking_numbers[start:end],))threads.append(thread)# 启动线程for thread in threads:thread.start()# 等待线程结束for thread in threads:thread.join()# 输出爬取结果print("爬取完成")

这个代码实现了:

  1. 多线程爬取:通过定义线程数和线程锁来实现多线程爬取,加速爬取速度。

  2. 自动识别快递公司:通过定义快递公司列表和快递公司匹配的正则表达式来实现自动识别快递公司。

  3. 数据存储:通过连接MongoDB数据库,并定义数据结构,将爬取的快递信息保存到MongoDB中。

  4. 可视化展示:通过使用matplotlib库,将爬取的快递信息进行数据可视化展示。

  5. 自动重试:虽然没有在代码中体现,但是可以加入重试机制,当网络连接不稳定或者请求失败时自动重试。

  6. 验证码识别:当出现验证码时,通过下载验证码图片,使用pytesseract库进行验证码识别,自动输入验证码。

需要注意的是,这个示例代码只是一个简单的爬虫示例,实际的爬虫任务可能更加复杂。在实际的爬虫开发中,需要根据具体的场景和需求来选择使用哪些技术和工具来完成爬虫任务。


http://www.ppmy.cn/news/39211.html

相关文章

2021蓝桥杯真题大写 C语言/C++

题目描述 给定一个只包含大写字母和小写字母的字符串,请将其中所有的小写字母转换成大写字母后将字符串输出。 输入描述 输入一行包含一个字符串。 输出描述 输出转换成大写后的字符串。 输入输出样例 示例 输入 LanQiao 输出 LANQIAO 评测用例规模与约定 对于…

如何自动填充creatTime和updateTime两种字段

1.mysql自带功能 首先是较为常见的,在mysql数据库里设置,但是我的mysql版本不支持该方法,如果尝试了后报错了请直接看方法二 sql语句预览 createTime timestamp not null default CURRENT_TIMESTAMP comment "创建时间", upd…

软考网络工程师要怎么复习?

一、明确考试重点和难点 网络工程师考试主要考察网络基础知识、网络架构设计、网络安全、网络管理等方面的知识。因此,我们在复习的时候,一定要明确考试重点和难点,将重点知识点逐一梳理,逐一掌握。 二、查漏补缺 在进行复习的…

13.网络爬虫—多进程详讲(实战演示)

网络爬虫—多进程详讲一进程的概念二创建多进程三进程池四线程池五多进程和多线程的区别六实战演示北京新发地线程池实战前言: 🏘️🏘️个人简介:以山河作礼。 🎖️🎖️:Python领域新星创作者,C…

TCP协议二:TCP状态转换(重要)

TCP状态转换分析https://www.bilibili.com/video/BV1iJ411S7UA?p44&spm_id_frompageDriver&vd_sourced239c7cf48aa4f74eccfa736c3122e65 TCP状态转换图 粗实线:主动端 虚线: 被动端 细实线:内核操作 状态分析 CLOSED&#xff1…

springboot项目前端ajax01

在我现在看来,ajax就好像是一个快速反应的内存,有很多的时候,ajax是有数据的。这个很好。 01.ajax函数在js中写的, function doGetActivitys(){ debugger //1.定义请求参数 var params“”; //2.定义请求url (前面加/为绝对路径&…

IDEA已经导入了jar包 还是提示找不到类(解决!!!)

项目代码check到本地,导入到idea中后,编译的时候很多类都报错了,打开发现有些框架中的类找不到。 报错:xxxx程序包找不到,xxxx类找不到 类似我框起来的地方是 报红的,utils这个包都找不到 解决方法: 网上1: 项目是依赖了这个jar包的,打开项目配置,查看依赖树: id…

linux服务器安装tomcat详细步骤

1、先下载linux版本的tomcat压缩包,示例压缩包为:apache-tomcat-8.0.53.tar.gz(推荐tomcat8版本) 下载地址:Index of /dist/tomcat/tomcat-8/v8.0.53/bin 2、 使用WinSCP工具(工具无限制,只要能…