第十五天-爬虫项目实战

目录

1.介绍

2.代码

1.main.py

2.PageSider.py

3.DetailSpider.py

4.DataParse.py

5.Constant.py

6.HanderRequest.py


1.介绍

1. 使用多线程爬取网站

2.爬取数据后保存至excel

3.爬取网站(仅做测试)网创类项目爬取:https://www.maomp.com/

4..实现效果

2.代码

1.main.py

# coding:utf-8
import threading

import requests
from  queue import Queue
from PageSpider import PageSpider
from DetailSpider import DetailSpider
from DataParse import DataParse
import xlsxwriter
import time
"""
爬取网站:https://www.maomp.com/wzjc/
爬取信息,保存至Excel
"""

def start_page(threadsize,page_queue,detail_queue):
    # 开启线程,开始采集page页面
    page_spider_threadsize = threadsize
    page_spider_list = []
    for i in range(1,page_spider_threadsize+1):
        pageSpiderThread = PageSpider(thread_name="页面采集线程"+str(i), page_queue=page_queue, detail_queue=detail_queue)
        # 启动线程
        pageSpiderThread.start()
        page_spider_list.append(pageSpiderThread)
    # 查看队列是否有数据
    while not page_queue:
        pass
    # 释放资源
    for page_spider in page_spider_list:
        if page_spider.is_alive():
            page_spider.join()


def start_detail(threadsize,detail_queue,data_queue):
    # 开启线程,开始采集page页面
    detail_spider_threadsize = threadsize
    detail_spider_list = []
    for i in range(1, detail_spider_threadsize + 1):
        detailSpiderThread = DetailSpider(thread_name="详情页采集线程" + str(i), detail_queue=detail_queue,
                                      data_queue=data_queue)
        # 启动线程
        detailSpiderThread.start()
        detail_spider_list.append(detailSpiderThread)
    # 查看队列是否有数据
    while not detail_queue:
        pass
    # 释放资源
    for detail_spider in detail_spider_list:
        if detail_spider.is_alive():
            detail_spider.join()

def start_data_parse(threadsize,data_queue,book):
    # 开启线程,开始采集page页面
    lock=threading.Lock()
    sheet1 = book.add_worksheet("sheet1")
    title_data = ("网址", "标题", "发布时间", "内容")
    # 添加表头
    for index, title_datum in enumerate(title_data):
        sheet1.write(0, index, title_datum)

    spider_list = []
    for i in range(1, threadsize + 1):
        thread = DataParse(thread_name="数据解析线程" + str(i), data_queue=data_queue,lock=lock,sheet=sheet1)
        # 启动线程
        thread.start()
        spider_list.append(thread)
    # 查看队列是否有数据
    while not data_queue:
        pass
    # 释放资源
    for parse in spider_list:
        if parse.is_alive():
            parse.join()

def main(xlswriter=None):
    #定义页面队列,存放page页信息
    page_queue = Queue()
    #定义详情页队列
    detail_queue = Queue()
    #定义详情页数据队列
    data_queue = Queue()
    page_start=1
    page_end=1
    for i in range(page_start,page_end+1):
        page_url="https://www.maomp.com/wzjc/page/{}/".format(i)
        page_queue.put(page_url)
    print("页面队列:",page_queue.qsize())

    #启动采集分页
    start_page(threadsize=3,page_queue=page_queue,detail_queue=detail_queue)
    #启动详情页采集
    start_detail(threadsize=3, detail_queue=detail_queue, data_queue=data_queue)
    # 启动数据解析
    #创建存放excel文件夹
    book = xlsxwriter.Workbook(time.strftime("%Y%m%d%H%M%S",time.gmtime())+"文件.xlsx")
    start_data_parse(threadsize=5,data_queue=data_queue,book=book)
    book.close()
    print("分页数据个数:",page_queue.qsize())
    print("详情页数据个数:", detail_queue.qsize())
    print("数据数据个数:", data_queue.qsize())

if __name__ == '__main__':
   main()

2.PageSider.py

# coding:utf-8
import threading
from lxml import etree
import HanderRequest


class PageSpider(threading.Thread):
    """
    页面url,请求多线程类
    """

    def __init__(self,thread_name,page_queue,detail_queue):
        super(PageSpider,self).__init__()
        self.thread_name=thread_name
        self.page_queue=page_queue
        self.detail_queue=detail_queue

    def parse_detail_url(self,content):
        """
        解析page页获取详情页url
        :param content:  page页text
        :return:  返回详情页url
        """
        #页码返回数据html实例化
        item_html=etree.HTML(content)
        #解析出索引详情页URL
        detail_urls=item_html.xpath("//h2[@class='entry-title']/a/@href")
        for url in detail_urls:
            #将详情页url存放到队列中
            self.detail_queue.put(url)

    def run(self):
        #实际发送请求
        print("{}启动".format(self.thread_name))
        #需要从page_queue队列中获取数据
        try:
            while not self.page_queue.empty():
            #从队列中获取数据,并设置为非阻塞状态
               page_url= self.page_queue.get(block=False)
               #请求页面链接
               response_text=HanderRequest.send_reqeust(page_url)
               if response_text:
                   #解析详情url
                   self.parse_detail_url(response_text)
        except Exception as e:
            print("{} 执行异常:{}".format(self.thread_name,e))

        print("{}结束".format(self.thread_name))

3.DetailSpider.py

# coding:utf-8
import threading
from lxml import etree
import HanderRequest


class DetailSpider(threading.Thread):
    """
    详情页url,请求详情页
    """

    def __init__(self,thread_name,detail_queue,data_queue):
        super(DetailSpider,self).__init__()
        self.thread_name=thread_name
        self.data_queue=data_queue
        self.detail_queue=detail_queue


    def run(self):
        #实际发送请求
        print("{}启动".format(self.thread_name))
        #需要从page_queue队列中获取数据
        try:
            while not self.detail_queue.empty():
            #从队列中获取数据,并设置为非阻塞状态
               detail_url= self.detail_queue.get(block=False)
               #请求页面链接
               response_text=HanderRequest.send_reqeust(detail_url)
               if response_text:
                   data={
                       "url":detail_url,
                       "html_content":response_text
                   }
                   #存放data_queuq数据
                   self.data_queue.put(data)

        except Exception as e:
            print("{} 执行异常:{}".format(self.thread_name,e))

        print("{}结束".format(self.thread_name))

4.DataParse.py

# coding:utf-8
import threading
from lxml import etree
import Constant



class DataParse(threading.Thread):
    """
    详情页数据处理
    """

    def __init__(self,thread_name,data_queue,lock,sheet):
        super(DataParse,self).__init__()
        self.thread_name=thread_name
        self.data_queue=data_queue
        self.lock=lock
        self.sheet=sheet


    def __list_join(self,list):
        return "".join(list)

    def __parse(self,data):
        """
        解析data_queue数据
        保存至excel中
        :return:
        """

        html= etree.HTML(data.get("html_content"))
        data={
            "url":data.get("url"),
            "title": self.__list_join(html.xpath("//h1[@class='entry-title']/text()")),
            "put_date":self.__list_join(html.xpath("//span[@class='my-date']/text()")),
            "content_html":self.__list_join(html.xpath("//div[@class='single-content']//p/text()"))
        }
        #多线程,使用lock来进行控制并发
        with self.lock:
            #写入Excel
            for index,e in enumerate(data):
                self.sheet.write(Constant.CURR_EXCEL_COL,index,data.get(e))
            Constant.CURR_EXCEL_COL += 1

    def run(self):
        #实际发送请求
        print("{}启动".format(self.thread_name))
        #需要从page_queue队列中获取数据
        try:
            while not self.data_queue.empty():
                #从队列中获取数据,并设置为非阻塞状态
                data_content= self.data_queue.get(block=False)
                #解析html数据
                self.__parse(data_content)

        except Exception as e:
            print("{} 执行异常:{}".format(self.thread_name,e))

        print("{}结束".format(self.thread_name))

5.Constant.py

# coding:utf-8

# excel写入到第几列
CURR_EXCEL_COL=1

6.HanderRequest.py

注意修改cookie

# coding:utf-8

import requests

def send_reqeust(url):
    #发送数据
    headers={
        "Cookie":"xxx",
        "user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36"
    }
    response=requests.get(url,headers=headers)
    if response.status_code==200 and response:
        return response.text

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

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

相关文章

【力扣白嫖日记】585.2016年的投资

前言 练习sql语句,所有题目来自于力扣(https://leetcode.cn/problemset/database/)的免费数据库练习题。 今日题目: 585.2016年的投资 表:Person 列名类型pidinttiv_2015floattiv_2016floatlatfloatlonfloat pid …

队列实现栈与栈实现队列

文章目录 前言一、使用队列实现栈二、使用栈实现队列 前言 1、用于巩固栈和队列。 2、本章是使用纯C语言实现的栈和队列,不懂的可以先看看这个喔:c语言实现栈和队列,当然这里直接用C的栈和队列会更方便哦。 3、利于复习C语言的知识点。 一、使…

吸猫毛空气净化器哪个好?推荐除猫毛效果好宠物空气净化器品牌

当下有越来越多的家庭选择养宠物!尽管家里变得更加温馨,但养宠可能会带来异味和空气中的毛发增多可能会带来健康问题,这是一个大问题! 不想家里弥漫着异味,特别是来自宠物便便的味道,所以需要一款能够处理…

跨境知识分享:什么是动态IP?和静态IP有什么区别?

对于我们跨境人来说,清楚地了解IP地址、代理IP等这些基础知识,并学会正确地使用IP地址对于保障店铺的安全性和稳定性至关重要,尤其是理解动态IP和静态IP之间的区别,以及如何利用这些知识来防止账号关联,对于每个电商卖…

什么是MAC地址? win10电脑查看MAC地址的多种方法

您是否知道连接到家庭网络的每件硬件都有自己的身份?正如每个设备都分配有自己的 IP 地址一样,每个硬件都有一个唯一的网络标识符。 该标识符称为MAC 地址。MAC 代表媒体访问控制。您可能需要 MAC 地址来解决网络问题或配置新设备。在 Windows 中查找您…

地图可视化绘制 | R-cartography 艺术地图绘制

本期推文我们介绍一个可以绘制颇具“艺术”风格地图的可视化包-cartography,主要涉及的内容如下: R-cartography 简介 R-cartography 实例应用 所有完整代码都已整理之我们的线上课程,有需要的同学v yidianshuyulove 咨询 R-cartography …

阿里云全面降价,释放了什么信号?

元宵节刚过,阿里云就放了一个大招—— 今天(2月29日)上午,阿里云发布通告,宣布全线下调云产品官网售价。这次降价涉及计算、存储、数据库等在内的100多款产品,平均降价幅度超过20%,最高降幅达55…

day07_分类管理EasyExcel品牌管理

文章目录 1 分类管理1.1 菜单添加1.2 表结构介绍1.3 页面制作1.4 列表查询1.4.1 需求分析1.4.2 后端接口CategoryCategoryControllerCategoryServiceCategoryMapperCategoryMapper.xml 1.4.3 前端对接category.jscategory.vue 2 EasyExcel2.1 数据导入导出意义2.2 EasyExcel简介…

1950-2022年各省逐年平均降水量数据

1950-2022年各省逐年平均降水量数据 1、时间:1950-2022年 2、指标:省逐年平均降水量 3、范围:33省(不含澳门) 4、指标解释:逐年平均降水数据是指当年的日降水量的年平均值,不是累计值&#…

【leetcode】环形链表✚环形链表II

大家好,我是苏貝,本篇博客带大家刷题,如果你觉得我写的还不错的话,可以给我一个赞👍吗,感谢❤️ 目录 1.环形链表解题拓展: 2.环形链表II 1.环形链表 点击查看题目 解题 思路: bool hasCycle…

【问题记录】pip install遇到“No space left on device“

一、pip安装包的过程中出现以下问题 二、问题溯源 【1】刚开始以为是空间不足,后来 df -h 看了一下,pip安装目录下空间绝对足够!明显不是空间不足的问题。 【2】后来查了一下,发现是home目录下的空间满了,pip安装时&…

一台工控机的能量

使用Docker搭建EPICS的IOC记录 Zstack EPICS Archiver在小课题组的使用经验 以前电子枪调试,用一台工控机跑起束测后台,这次新光源用的电子枪加工回来又是测试,又是用一台工控机做起重复的事,不过生命在于折腾,重复的…

计算机网络-网络互连和互联网(五)

1.路由器技术NAT: 网络地址翻译,解决IP短缺,路由器内部和外部地址进行转换。静态地址转换:静态NAT(一对一) 静态NAT,内外一对一转换,用于web服务器,ftp服务器等固定IP的…

C++ 入门(七)— 基本数据类型

文章目录 Void整数有符号整数无符号整数固定宽度的整数和size_t 浮点数布尔值字符类型转换 Void Void 是最容易解释的数据类型。void 没有类型 不返回值的函数 最常见的是&#xff0c;void 用于指示函数不返回值&#xff1a; void writeValue(int x) {std::cout <<…

【MySQL】数据库中常用的函数

目录 聚合函数COUNT()函数的多种用法COUNT(*)COUNT(主键)COUNT(1)COUNT(常量)COUNT(非主键)COUNT(distinct(字段)) COUNT()函数小结 字符函数length(str)函数&#xff1a;获取参数值的字节个数concat(str1,str2,...)函数&#xff1a;字符串拼接upper(str)、lower(str)函数:大小…

部署Docker私有镜像仓库Harbor

Harbor介绍 Harbor 是为企业用户设计的开源镜像仓库项目&#xff0c;包括了权限管理(RBAC)、LDAP、审计、安全漏洞扫描、镜像验真、管理界面、自我注册、HA等企业必需的功能&#xff0c;同时针对中国用户的特点&#xff0c;设计镜像复制和中文支持等功能。 官网&#xff1a;h…

kotlin开发环境搭建,算法题+JVM+自定义View

什么是中年危机 根据权威数据显示&#xff0c;国内IT程序员鼎盛时期是在25-27岁左右&#xff0c;30岁对于程序员而言完全是一个38线&#xff0c;接着就是转业转岗的事情&#xff0c;这一点在业界也算是一个共识了。 大学毕业步入IT行业普遍年龄也是在22岁左右&#xff0c;然而…

线程安全的队列

学习一下别人写的&#xff0c;线程安全的队列代码。https://github.com/markparticle/WebServer/blob/master/code/log/blockqueue.hhttps://github.com/markparticle/WebServer/blob/master/code/log/blockqueue.h /** Author : mark* Date : 2020-06-16* copy…

20240301作业

1.使用fwrite、fread将一张随意的bmp图片&#xff0c;修改成德国的国旗 #include <stdio.h> #include <string.h> #include <unistd.h> #include <stdlib.h> int main(int argc, const char *argv[]) {FILE* fp fopen("./gaoda.bmp","…

Attention 中的 Q, K, V

Attention 中的 Q, K, V flyfish Attention Is All You Need. Q query 查询 K key 键 V value 值 简单理解 一篇文章&#xff0c;文章的标题就是key&#xff0c;文章的内容就是V 使用搜索引擎时&#xff0c;输入到 搜索栏中的文本 就是 query 输入内容 query 与 文章标…