python爬虫爬取中国国际招标有限公司

python爬虫爬取中国国际招标有限公司

python爬取数据存储到redis中

#  -*- coding: utf-8 -*-
# 中国国际招标有限公司
import re
from datetime import datetime

import redis
import requests
from lxml import etree
from config import REDIS_IP, REDIS_PORT, REDIS_DB, REDIS_PASSWORD
from items.sql import MySQL


class Cntcitc:
    def __init__(self):
        self.redis = redis.Redis(host=REDIS_IP, port=REDIS_PORT, db=REDIS_DB, password=REDIS_PASSWORD,
                                 decode_responses=True, charset='UTF-8',
                                 encoding='UTF-8')
        self.db = MySQL()
        self.db.connect()
        self.name = '中国国际招标有限公司'
        self.url = 'https://www.cntcitc.com.cn/searchPage.html'
        self.api_url = 'https://www.cntcitc.com.cn/search.html'
        self.today = datetime.today().strftime('%Y-%m-%d')
        self.counter_key = f"cntcitc:counter:{self.today}"
        self.overall_cycle = False
        self.headers = {
            "referer": self.url,
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36",
        }

    def get_data(self, key, page=1):
        payload = {
            'channelId': '-1',
            'key': key,
            'startTime': "2024-06-18",
            'endTime': '',
            'currentPage': page
        }
        con = requests.post(url=self.api_url, headers=self.headers, data=payload).content.decode('utf8')
        html = etree.HTML(con)
        content_text = ''.join(html.xpath('/html/body/div/div/form/div[2]/ul/text()'))
        content = content_text.strip()
        print(f"key:{key},爬取内容:{content}")
        if content == "未查询到相关内容":
            return None
        else:
            return html

    # 获取总页数
    def get_page(self, key):
        html = self.get_data(key)
        if html is not None:
            pageText = ''.join(html.xpath('/html/body/div/div/form/div[2]/div/span[2]/text()'))
            # 使用正则表达式匹配“共x页”格式的文本
            match = re.search(r"共\d+页", pageText)
            # 如果匹配成功,去除中间空格并提取数字
            if match:
                # 去除中间空格
                cleaned_text = re.sub(r"\s", "", match.group())
                # 提取数字
                page = re.search(r"\d+", cleaned_text).group()

            else:
                page = None
            return page
        else:
            return None

    def spider(self, key):
        pages = self.get_page(key)
        if pages is not None:
            self.overall_cycle = False
            # 爬取增量数据
            last_page_key = f"cntcitc:last_link:{key}"
            last_page_link = str(self.redis.get(last_page_key) or "")
            try:
                for page in range(1, int(pages) + 1):
                    if self.overall_cycle:
                        break
                    html = self.get_data(key, page)
                    if html is not None:
                        for i in range(1, 16):
                            title = ''.join(
                                html.xpath(f'/html/body/div/div/form/div[2]/ul/li[{i}]/a/text()')).strip()
                            if title == "":
                                break
                            suffix_link = ''.join(
                                html.xpath(f'/html/body/div/div/form/div[2]/ul/li[{i}]/a/@href'))
                            link = f"https://www.cntcitc.com.cn/{suffix_link}"
                            if last_page_link == link:
                                self.overall_cycle = True
                                break
                            publish_time_text = ''.join(
                                html.xpath(f'/html/body/div/div/form/div[2]/ul/li[{i}]/text()'))
                            # 使用正则表达式匹配日期
                            match = re.search(r'\d{4}-\d{2}-\d{2}', publish_time_text)
                            publish_time = ""
                            if match:
                                date_str = match.group()
                                publish_time = date_str

                            self.store_to_redis(link, title, publish_time, key)
                            if last_page_link == "":
                                self.redis.set(last_page_key, link)
                                last_page_link = link
            except Exception as e:
                print(f"中国国际招标有限公司爬虫出现异常: {e}")
                self.redis.set(last_page_key, "")

    def store_to_redis(self, link, title, show_times, key):
        if self.redis.exists(link):
            existing_keys = self.redis.hget(link, 'keys').split(',')
            if key not in existing_keys:
                existing_keys.append(key)
                self.redis.hset(link, 'keys', ','.join(existing_keys))
                self.redis.hset(link, 'is_synced', 'false')
        else:
            self.redis.hset(link, mapping={
                'title': title,
                'show_times': show_times,
                'keys': key,
                'is_synced': 'false'
            })
            # 设置过期时间为28天(2419200秒)
            self.redis.expire(link, 2419200)
        self.redis.incr(self.counter_key)

    def get_today_crawl_count(self):
        return int(self.redis.get(self.counter_key) or 0)

    def process(self):
        key_list = ['动漫', '引流', '银行', '业务']
        for key in key_list:
            self.spider(key)
        print(f'中国国际招标有限公司的爬取数据数量为:{self.get_today_crawl_count()}')


if __name__ == '__main__':
    bank_cntcitc = Cntcitc()
    bank_cntcitc.process()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/777117.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

维护和管理LDAP之OpenDJ

目录 基本介绍 服务专有名词 安装 命令行工具 密码管理 重置管理员密码 管理服务器进程 管理索引 如何搜索 管理索引 管理目录数据 测试数据 导出数据 导入数据 LDIF文件数据查看和比较 数据存储-Backends 配置连接 开启 HTTP/HTTPS连接 使用 REST访问 -open…

三、虚拟机连接外网

来源网站:山海同行 来源地址:https://shanhaigo.cn 本篇资源:以整理分类并关联本篇地址 本篇地址:https://shanhaigo.cn/courseDetail/1805875642621952000 一、配置虚拟机 1. 选择NAT模式 编辑虚拟网络设置,选择NAT…

1分钟完美音质克隆:配音软件全面超越,

随着人工智能技术的不断进步,配音软件在提供高质量声音输出方面取得了显著成就。本文所讨论的软件产品,凭借其卓越的性能,已成为自媒体创作者在声音制作方面的首选工具。 2. 软件产品概述 该软件利用先进的算法和机器学习模型,为…

docker也能提权??内网学习第6天 rsync未授权访问覆盖 sudo(cve-2021-3156)漏洞提权 polkit漏洞利用

现在我们来说说liunx提权的操作:前面我们说了环境变量,定时任务来进行提权的操作 rsync未授权访问覆盖 我们先来说说什么是rsync rsync是数据备份工具,默认是开启的873端口 我们在进行远程连接的时候,如果它没有让我们输入账号…

IT入门知识第八部分《人工智能》(9/10)

1.引言 在当今数字化时代,人工智能(AI)和机器学习(ML)已成为推动技术革新的关键力量。它们不仅改变了我们与机器的互动方式,还极大地拓展了解决问题的可能性。本文将深入探讨人工智能和机器学习的基础&…

哨兵1SAR空间数据包协议数据单元文档(七)

《哨兵1SAR空间数据包协议数据单元》文档对数据包的结构进行了详细描述,并提供了用户数据的格式和解码算法。 原文链接: 哨兵1SAR空间数据包协议数据单元文档英文版 同系列中的其他文章篇链接: 哨兵1SAR空间数据包协议数据单元文档(一) 哨兵…

Day05-03-Nexus仓库

Day05-03-Nexus仓库 05-nexus-仓库1. 概述2. 极速部署指南2.1 下载2.2 部署2.3 配置2.4 连接使用nexus2.4 编译与测试 3. 总结 05-nexus-仓库 1. 概述 背景: maven编译的时候,npm/cnpm编译,需要下载大量的依赖包。这些依赖包在每一次构建的时候都需要使…

横截面交易策略:概念与示例

数量技术宅团队在CSDN学院推出了量化投资系列课程 欢迎有兴趣系统学习量化投资的同学,点击下方链接报名: 量化投资速成营(入门课程) Python股票量化投资 Python期货量化投资 Python数字货币量化投资 C语言CTP期货交易系统开…

大模型成为软件和数据工程师

前言 想象一下这样一个世界:人工智能伙伴负责编码工作,让软件和数据工程师释放他们的创造天赋来应对未来的技术挑战! 想象一下:你是一名软件工程师,埋头于堆积如山的代码中,淹没在无数的错误中&#xff0…

Rust作用域和遮蔽

作用域和遮蔽 变量绑定有一个作用域(scope),它被限定只在一个代码块(block)中生存(live)。 代码块是一个被 {} 包围的语句集合。另外也允许[变量遮蔽][variable-shadow](variable s…

【代码随想录——图论——岛屿问题】

1.岛屿数量 https://kamacoder.com/problempage.php?pid1171 1.1 深度优先搜索 package mainimport "fmt"var direction [][]int{{0, 1}, {0, -1}, {1, 0}, {-1, 0}}func main() {var M, N intfmt.Scanln(&N, &M)sea : make([][]int, N)visited : make…

SSRS中生成二维码

1.二维码搭建, fastapi,qrcode,python-barcode from fastapi import FastAPI, HTTPException from pydantic import BaseModel import qrcode from io import BytesIO from fastapi.responses import StreamingResponse import barcode from barcode.writer import ImageWrite…

关于Unity粒子(2D序列帧粒子)的旋转、StartRotation值用脚本怎么动态设置

今天要用粒子做一个拖尾效果。由于对象的移动可以向任何方向,所以作为拖尾的粒子要根据方向做相应的旋转。 1.没有旋转的情况(物体向下移动)时,默认是下面这样的。 粒子发射器的形状是一个向上的长方形,粒子的移动方向…

在Linux系统中配置GitHub的SSH公钥

在Linux系统中配置GitHub的SSH公钥,可以让您无需频繁输入密码即可与GitHub仓库进行交互,提高工作效率。以下是配置步骤: 第一步: 检查SSH密钥是否存在 首先,检查您的用户目录下的.ssh文件夹中是否已有SSH密钥。打开终端&#xff0…

Interview preparation--Https 工作流程

HTTP 传输的弊端 如上图,Http进行数据传输的时候是明文传输,导致任何人都有可能截获信息,篡改信息如果此时黑客冒充服务器,或者黑客窃取信息,则其可以返回任意信息给客户端,而且不被客户端察觉,…

Java经典面试题将一个字符串数组进行分组输出,每组中的字符串都由相同的字符组成

Java经典面试题将一个字符串数组进行分组输出,每组中的字符串都由相同的字符组成 题目: 将一个字符串数组进行分组输出,每组中的字符串都由相同的字符组成 举个例子:输入[“eat”,“tea”,“tan”,“ate”,“nat”,“bat”] 输出…

考CFA ESG踩过的坑,想考CFA ESG的同学,可以收藏

考CFA ESG踩过的坑 考证也是蹭热点, 2020年,那时是云,阿里云,腾讯云,华为云竞相绽放, 再过点时间,好像安全方面的证书,如油炸爆米花一样,噼里啪啦地蹦了出来&#xff0…

基于STM32与ESP8266的智能电表设计与实现:实时监测,远程管理(附代码实例)

一、项目背景 随着物联网技术的快速发展,传统电表已经无法满足智能电网对用电信息采集、分析和管理的需求。智能电表作为新一代电能计量设备,具有实时监测、远程抄表、用电分析等功能,是实现智能电网的重要基础设施。 本项目旨在设计并实现…

猫狗图像分类-划分数据集

📚博客主页:knighthood2001 ✨公众号:认知up吧 (目前正在带领大家一起提升认知,感兴趣可以来围观一下) 🎃知识星球:【认知up吧|成长|副业】介绍 ❤️如遇文章付费,可先看…

【Linux】:程序地址空间

朋友们、伙计们,我们又见面了,本期来给大家解读一下有关Linux程序地址空间的相关知识点,如果看完之后对你有一定的启发,那么请留下你的三连,祝大家心想事成! C 语 言 专 栏:C语言:从…