利用Selenium(爬虫)爬取物流信息,并用邮件提醒自己物流更新

2023-11-02

受疫情影响,快递无法全面复工,商家在过年期间又压了一堆未发货的订单。现在下单一个快递,商家迟迟无法发货,就算发了货,物流也慢的跟蜗牛一样。每天就是打开淘宝看物流信息,物流信息又没更新,关淘宝,为了节省这些时间,不在焦虑中度过,写了这么一个功能。(*^__^*) 嘻嘻……

 

准备工作

pip install lxml

pip install selenium

pip install smtplib

pip install email

谷歌浏览器

要爬取的网站 https://kuaidi.chawuliu.cn/

符合自己谷歌浏览器的chromedriver 地址http://npm.taobao.org/mirrors/chromedriver/

 

谷歌浏览器的版本在设置->左下角 关于Chrome 查看

因为我的浏览器是79.0.3945.88,所以下载chromdriver的时候选择79.0.3945.36/,要选择与自己浏览器对应的版本,不然会报错。

 

 

开启邮箱的SMTP服务

这里我使用的是QQ邮箱,只有开启smtp服务,python才能为你代发邮件。开启之后会有一个授权码,保存好这个,Python就是用这个授权码去登录你的邮箱的。

 

 

 

 

编码阶段

准备了这么久,路已经铺平了,就差这么一段代码了。

简单解释一下我的代码,有三个文件。

Express.py  函数运行的入口

SendEmail.py 处理发送邮件的类

Reptile.py 查询物流的爬虫类

还有之前下载的chromedriver,放在同一文件夹下,linux跟windows下的chromedriver是不一样的。

linux

windows

Express.py 

import time
from multiprocessing import Process

from Reptile import Reptile
from SendEmail import SendEmail

k = 0
count = 0

def main():

        sendManage = SendEmail(开启STMP服务的邮箱, 目标邮箱, 'smtp.qq.com', 开启STMP服务时的密码)
        #sendManage = SendEmail('xxx.@qq.com', 'xxx.@qq.com', 'smtp.qq.com', 'xxx')
        # 我是用顺丰物流单号,其他快递公司没有试过
        reptileManage = Reptile('快递单号')

        global k
        global count
	  count += 1
        data = reptileManage.start()
        # 上一次的信息条数跟这一次不一样,说明物流更新了
        if k != len(data):
                k = len(data)
                count = 0
                # 发送邮件频率不能过高,否则服务器会限制发送,导致代码报错
                sendManage.sendEmail(data)

def run():
    count = 7199
    while count > 0:
        print(count, end='')
        time.sleep(1)
        print('\r', end='')
        count -= 1

if __name__ == '__main__':
        

        while True:
            p = Process(target=run).start()
            main()
            # 两个小时运行一次
            time.sleep(7200)
            # 30天没更新 停止运行
            if count > 360:
                    break

 

SendEmail.py

# 发送email所需的头文件
import smtplib
from email.mime.text import MIMEText
from email.header import Header


# 构建一个发送邮件的类
class SendEmail:
    def __init__(self, author, target, server, password):
        self.authorEmail = author
        self.targetEmail = target

        # 发信服务器和授权码
        self.smtp_server = server
        self.password = password

    def writeEmail(self, data):
        # 邮箱正文内容,第一个参数为内容,第二个参数为格式(plain 为纯文本),第三个参数为编码
        msg = MIMEText('send by python', 'plain', 'utf-8')

        # 邮件头信息
        msg['From'] = Header(self.authorEmail)
        msg['To'] = Header(self.targetEmail)
        content = ''
        for text in data:
            content = content + text + '\n'
        msg['Subject'] = Header(content)
        return msg

    def sendEmail(self, data):
        msg = self.writeEmail(data)

        # 开启发信服务,这里使用的是加密传输
        server = smtplib.SMTP_SSL(host=self.smtp_server)
        server.connect(host=self.smtp_server, port=465)

        # 登录发信邮箱
        server.login(self.authorEmail, self.password)
        # 发送邮件
        server.sendmail(self.authorEmail, self.targetEmail, msg.as_string())
        # 关闭服务器
        server.quit()

 

Reptile.py

# selenium
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.keys import Keys

import re
import time
import lxml.html

class Reptile:
    def __init__(self, Number):
        self.Number = Number
        # 要爬取的网站
        self.url = 'https://kuaidi.chawuliu.cn/'
        # linux是一个叫chromedriver的文件, 在windows下是一个exe
        # windows的用户要改一下这里
        self.driver = webdriver.Chrome('./chromedriver')


    def failMessage(self):
        list = []
        list.append('浏览器在请求的时候发生错误,请查看错误信息!!!')
        return list

    def succeedMessage(self):
        list = []
        selector = lxml.html.fromstring(self.driver.page_source)
        contentList = selector.xpath('//div/ul/li[@class="feed-item"]')
        for item in contentList:
            item_time = item.xpath('div/div[@class="feed-item_time"]/text()')[0]
            item_date = item.xpath('div/div[@class="feed-item_date"]/text()')[0]
            item_content = item.xpath('div[@class="feed-item_content"]/text()')[0]
            print(item_time, ' ', item_date, ' ', item_content)
            list.append(item_time + ' ' + item_date + ' ' + item_content)
        return list

    #  切换浏览器的窗口
    def turnPage(self):
        handles = self.driver.window_handles  # 获取当前窗口句柄集合(列表类型)
        for handle in handles:  # 切换窗口
            # current_window指的是driver.page_source
            if handle != self.driver.current_window_handle:
                self.driver.switch_to.window(handle)
                break

    def start(self):
        self.driver.get(self.url)

        # 等待元素('searchbox')的出现,最多等待300s
        try:
            WebDriverWait(self.driver, 300).until(EC.presence_of_element_located((By.ID, 'searchbox')))
        except Exception as _:
            print(_)
            return self.failMessage()

        inputNumber = self.driver.find_element_by_id('searchbox')
        inputBtn = self.driver.find_element_by_id('searchBtn')

        # 往网页输入物流单号,并回车搜索
        inputNumber.clear()
        inputNumber.send_keys(self.Number)
        inputBtn.send_keys(Keys.RETURN) # 回车

        time.sleep(5)

        # 回车后会生成新窗口,所以切换窗口
        self.turnPage()

        try:
            WebDriverWait(self.driver, 300).until(EC.presence_of_element_located((By.ID, 'searchbox')))
        except Exception as _:
            print(_)
            return self.failMessage()

        selector = lxml.html.fromstring(self.driver.page_source)
        link = selector.xpath('/html/body/center/a[2]/@href')[0]

        # 这个是最后我们要得到的物流信息
        self.driver.get(link)
        try:
            WebDriverWait(self.driver, 300).until(EC.presence_of_element_located((By.CLASS_NAME, 'feed-container')))
        except Exception as _:
            print(_)
            return self.failMessage()

        data = self.succeedMessage()
        self.driver.quit() # 关闭浏览器
        return data

 

效果

上阿里云腾讯租个虚拟主机,在那里可以24小时不间断运行,感觉更高端了。

下面是云主机给我发回来的邮件,还有在cmd窗口的图片。

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

利用Selenium(爬虫)爬取物流信息,并用邮件提醒自己物流更新 的相关文章

随机推荐

  • qt提升控件之后,编译报错

    引言 自定义的控件 在ui文件中将控件提升为自定义的控件 提升的时候没有指明提升的头文件的相对路径或者绝对路径 导致编译的时候无法找到相应的头文件 解决方法 1 在被提升的类的头文件前添加本机电脑所在的相对路径 2 在被提升的类的头文件前添
  • leveldb常见问题以及性能优化点

    本篇是leveldb最后一篇 这里主要把技术核心点 性能提升点或者面试可能会被问到进行总结 一 常见问题 1 leveldb key value内存 内存中保存的是所有key value吗 答 不是 搜索顺序 memtable immtab
  • 利用MATLAB中的newrb函数进行函数逼近

    RBF函数在神经网络控制中较为常见 MATLAB中早已集成了一个newrb的函数 在一些场景下使用起来还比较方便 尤其是涉及到进行函数逼近的时候 参考链接 http blog sina com cn s blog 9b8d0abd0101o
  • Android Studio连接自带模拟器失败怎么办?强烈建议使用第三方模拟器(含各类模拟器下载地址)

    学习安卓开发的小伙伴必然会碰到模拟器的启动问题 就算成功启动Android Studio自带的模拟器 使用起来也是十分缓慢 有时候卡起来是真想骂娘 服了他个老六 那么这个时候 如果有一个第三方模拟器 不仅简单好用 无需配置 而且美观快速零卡
  • 华为存储特性

    华为存储特性 1 SmartPartition SmartPartition是一种性能特性 根据不同业务特点分配存储系统的缓存资源来满足不同应用系统的服务质量要求 由于单个存储系统要面对的应用数量急剧增加 且各业务应用之间的I O特征不同
  • Android-第五节Menu菜单详解

    目录 一 Menu背景 二 Menu使用步骤 1 创建menu 2 设计menu 3 重写menu逻辑代码 4 运行效果 一 Menu背景 手机毕竟和电脑不同 它的屏幕空间非常有限 因此充分地利用屏幕空间在手机界面设计中就显得非常重要了 如
  • STM32 使用TIM2_CH1(PA15) 输出10K PWM信号

    PA15 gt TIM2 Remap CH1 1 apb init RCC APB1PeriphClockCmd RCC APB1Periph TIM2 ENABLE RCC APB2PeriphClockCmd RCC APB2Perip
  • JMM java内存模型

    java内存模型 即 java memory model 它定义了主存 工作内存抽象概念 底层对应着 CPU 寄存器 缓存 硬件内存 CPU 指令优化等 JMM 体现在以下几个方面 原子性 保证指令不会受到线程上下文切换的影响 可见性 保证
  • android 安装命令,【转载】android中APK包的安装以及adb命令的使用

    1 首先将 android sdk platform tools添加都path路径下 2 在控制台窗口中进入到你apk包所在的目录中 3 输入 abd unremount 第一次使用该命令的时候需要获取该命令的操作权限 4 打开androi
  • Filter、Interceptor的使用

    Filter Interceptor的使用 一 Filter Interceptor的区别 1 1 过滤器 Filter 1 2 拦截器 Interceptor 二 Filter Interceptor的使用 2 1 Filter 的实现步
  • 微信临时文件wxfile://tmp文件处理,微信小程序最新获取头像和昵称

    欢迎点击领取 前端面试题进阶指南 前端登顶之巅 最全面的前端知识点梳理总结 分享一个使用比较久的 技术栈 taro框架 vue3版本 解决在微信小程序获取微信头像时控制台报错 找不着wxfile tmp 文件路径 失败 原因如下 因为微信提
  • JS合并数组对象中key相同的数据(将数组里某个属性相同的对象合并成一个数组)

    将数组里某个属性相同的对象合并成一个数组 原数组如下 let resData name 住院医疗最高报销 tagName 医疗 insuredAmount 6000 name 身故赔付 tagName 寿险 insuredAmount 36
  • 80后创业故事之:兄弟散伙,创业失败

    在开始今天的故事之前 首先感谢这么多朋友关注我的文章 实在让我受宠若惊 我定倍加珍惜大家对我的支持 同时我也留意到这些天有一些朋友对我的故事也提出了一些质疑 怀疑是否杜撰 编造或者太过夸大其辞 本来我想出说一箩筐的理由来证明我所说的都是我自
  • AIGC参数量节节攀升,对存储带来的挑战如何解决?

    引言 近期 AIGC 相关产品如同雨后春笋一般不断涌现 但在技术层面 大家普遍的关注点更多集中在性能方面 却经常忽略了存储对推理和训练效率的影响 以及 AIGC 内容可能带来的合规风险 我们特邀腾讯云存储的产品负责人 崔剑老师和益企研究院创
  • 性能自动化+locust

    性能自动化 locust 仅作为个人笔记 如有雷同 请联系删除 性能测试基础 1 性能测试相关概念 性能测试 测试软件的性能表现 考量软件运行的如何 一般关注时间 效率 资源占用等情况 响应时间 应用系统从用户发出请求开始 到客户端接收到所
  • 你想知道的大数据知识都在这里

    欢迎大家前往腾讯云 社区 获取更多腾讯海量技术实践干货哦 毋庸置疑 现如今是属于大数据 Big Data 的 革命性的时代 从社交媒体到企业 每时每刻都在产生大量的数据 无所作为 从而把这样的宝藏白白浪费掉是及其愚蠢的 企业已经学会了收集大
  • OV7670配置和调试总结

    废话后面说 先直接上OV7670寄存器的配置部分 const uint8 t OV7670 Reg 2 Frame Rate Adjustment for 24Mhz input clock 30fps PCLK 24MHz 0x11 0x
  • tomcat部署时注意修改目录路径

    原文 https blog csdn net qq 15676547 article details 81208991 每次发布war包 都会把附件给覆盖了 为了解决这个问题 我们需要把目录给修改到别处 方法如下
  • SSH远程访问AWS EC2

    步骤1 启动Amazon EC2实例 视频演示 启动AWS EC2实例 导航到Amazon EC2并开始启动新实例 在本教程中 我将使用Amazon Linux 2 AMI HVM 操作系统 创建一个没有规则的新安全组 例如MediumSG
  • 利用Selenium(爬虫)爬取物流信息,并用邮件提醒自己物流更新

    受疫情影响 快递无法全面复工 商家在过年期间又压了一堆未发货的订单 现在下单一个快递 商家迟迟无法发货 就算发了货 物流也慢的跟蜗牛一样 每天就是打开淘宝看物流信息 物流信息又没更新 关淘宝 为了节省这些时间 不在焦虑中度过 写了这么一个功