多进程爬虫实战-摩托车网

news2024/11/24 4:29:26
前言
最近有遇到很多私信让我讲一讲多进程的爬虫,我发现大家对爬虫的框架写法和进程的理解有很多的问题和疑问,这次就带来一个小实战让大家理解多进程爬虫以及框架的写法

由于进程爬虫会对任何服务器都有一定的影响,本文仅供学习交流使用,切勿拿去做什么不好的事情,要做一个合法的爬虫写手。

📝个人主页→数据挖掘博主ZTLJQ的主页

b1691e6f246947eeb06ee06469621bc2.gif

个人推荐python学习系列:

☄️爬虫JS逆向系列专栏 - 爬虫逆向教学

☄️python系列专栏 - 从零开始学python

 


首先是网址摩托车品牌大全|摩托车报价 那么这个网址就是我们要进行爬取的目标

那其实有一定爬虫基础的同学呢就可以看出URL后缀pinpai.asp?ppt=&slx=0&skey=&page=1其实很好构造,一般看到这样的网站不会去想有什么动态的处理,不放心的话点击下一页然后打开F12抓包看看有没有变化,或者看一下点击下一页以后网站是不是不需要刷新就可以下一页就能判断是不是有什么动态处理了。

那么我们通过分析就知道这个网站是一个简单的静态页面,那么翻页的问题直接就搞定了,只需要把URL中的 ppt=&slx=0&skey=&page=1     page更换页码就可以了,但是我们既然是使用多进程,那就不要像之前一样写个简单的for循环  让爬虫程序一页一页的去翻。

那么我们的逻辑就很清晰,我们既然不想一页一页的翻就直接获取到尾页,如图:

 点击尾页直接就能知道一共有多少页数据,为了防止每次都更新,所有直接在页面获取到尾页的数据即可,各位小伙伴可能进去以后就会疑惑,不点击尾页不会显示出有多少页那么怎么抓到有多少页数据呢?

这里就要和大家说一下,有时候写爬虫不要光想,打开F12看一下尾页哪里,a标签的href就直接有数据了,所以是可以直接抓的如下图:

 那么这个思路清楚以后就可以开始先写代码了,代码如下:

res = requests.get('https://www.2smoto.com/pinpai/')
text = xl(parse_xpath(res,"//a[contains(text(),'尾页')]/@href"))
# 这上面是开启多进程 然后获取这个网址总共有多少页  然后设置 每一个进程处理一页的数据

# 接下来取得尾页数据
count = text.split('=')[-1]

# 多进程
# 获取cpu 核心数量
cpu_count = multiprocessing.cpu_count() # 12个进程
pool = multiprocessing.Pool(processes=cpu_count)

for i in range(1,int(count)+1):
    url = 'https://www.2smoto.com/pinpai.asp?ppt=&slx=0&skey=&page={}'.format(i)
    pool.apply_async(request,(url,))
pool.close() # 关闭进程池  关闭之后 不能再向进程池中添加进程
pool.join() # 当进程池中所有进程执行完后,主进程才可以继续执行
print('程序用时{}'.format(time.time() - s))

代码中先构造requests请求,然后通过上面我所说的获取到尾页的数据,text = xl(parse_xpath(res,"//a[contains(text(),'尾页')]/@href")),接下来就是每一个进程处理一页的数据,这个和线程不同,进程和线程的区别你可以理解为,进程相当于是按页分,线程是页中每一条数据来分。

我这里是直接获取CPU的核心数量就用了12个进程你们自己可以单独设置自己想要的数值。

接下来就是简单的for循环。最后要记得关闭进程池。

总体的逻辑分析清晰以后就是每一条数据的获取方式了,这个就非常简单了,使用XPATH或者正则表达式都可以,看你喜欢,我这里提供代码给大家参考,由于只是为了讲解就只爬取品牌和价格其他的东西你们喜欢可以自己加,代码如下:

goods_list = parse_xpath(res,'//ul[@class="goods_list"]/li')
for goods_lists in goods_list:
    title = xl(goods_lists.xpath('./p[@class="name"]/a/@title'))
    price = xl(goods_lists.xpath('./p[@class="price_wrap"]/span/text()'))
    print({'品牌':title,'价格':price})
    print('='*50)

最后就是设置一个请求头即可,当然不要忘记查看一下这个网站的编码方式,我这里直接告诉大家如下图可以找到:

 到这里其实基本上一整个代码都已经结束了,但是这次还要给大家提供一种框架的写法,也就是通用的爬虫框架,我下面会给大家一一介绍:

 如图是一个非常简单的爬虫框架,我直接给大家代码,大家复制就可以使用了,代码如下:

def request(url):
    """
    请求模块  负责网络请求
    :return:
    """

def parse_xpath(obg,tag):
    """
    负责 数据解析工作
    :return:
    """


def parse(res):
    """
    负责总体业务
    :return:
    """


def save():
    """
    负责存储数据
    :return:
    """


def run():
    """
    入口函数  开启任务
    :return:
    """

那么这个框架其实就一目了然了,请求区域,解析区域,总体业务,存储,入口函数都有,大家不要觉得框架是无用的,其实等同学们出来工作后,每天都是在用框架进行工作和学习,所以提早接触是好事

那么就把刚刚进程的爬虫放入到这个框架中去,就会是这个情况,代码如下:

def request(url):
    """
    请求模块  负责网络请求
    :return:
    """
    header = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36',
    }

    res = requests.get(url,headers=header)
    res.encoding = 'gb2312'
    if res.status_code == 200:
        parse(res)


def parse_xpath(obg,tag):
    """
    负责 数据解析工作
    :return:
    """
    html = etree.HTML(obg.text)
    res = html.xpath(tag)
    return res


def parse(res):
    """
    负责总体业务
    :return:
    """
    goods_list = parse_xpath(res,'//ul[@class="goods_list"]/li')
    for goods_lists in goods_list:
        title = xl(goods_lists.xpath('./p[@class="name"]/a/@title'))
        price = xl(goods_lists.xpath('./p[@class="price_wrap"]/span/text()'))
        print({'品牌':title,'价格':price})
        print('='*50)


def save():
    """
    负责存储数据
    :return:
    """
    pass


def run():
    """
    入口函数  开启任务
    :return:
    """
    res = requests.get('https://www.2smoto.com/pinpai/')
    text = xl(parse_xpath(res,"//a[contains(text(),'尾页')]/@href"))
    # 这上面是开启多进程 然后获取这个网址总共有多少页  然后设置 每一个进程处理一页的数据

    # 接下来取得尾页数据
    count = text.split('=')[-1]

    # 多进程
    # 获取cpu 核心数量
    cpu_count = multiprocessing.cpu_count() # 12个进程
    pool = multiprocessing.Pool(processes=cpu_count)

    for i in range(1,int(count)+1):
        url = 'https://www.2smoto.com/pinpai.asp?ppt=&slx=0&skey=&page={}'.format(i)
        pool.apply_async(request,(url,))
    pool.close() # 关闭进程池  关闭之后 不能再向进程池中添加进程
    pool.join() # 当进程池中所有进程执行完后,主进程才可以继续执行
    print('程序用时{}'.format(time.time() - s))

这样是不是就很方便了呢?这个框架到下一个网站,只需要改改URL这些就可以继续使用,所以框架的方便真的无法想象

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Linux后端服务器开发】C程序预处理

目录 一、源文件到可执行程序的过程 二、预定义符号 三、#define宏定义 四、条件编译 一、源文件到可执行程序的过程 预处理:去注释,宏替换,头文件展开,条件编译编译:c语言 ---> 汇编语言(语法分析…

JUC高级-0625

13. AbstractQueuedSynchronized之AQS 13.1 前置知识 公平锁和非公平锁可重入锁自旋思想LockSupport数据结构之双向链表设计模式之模板设计模式 13.2 AQS入门级别理论知识 AQS是什么? 字面意思:抽象的队列同步器,实现了通知唤醒的机制源代…

8通道250MSPS采样率16位AD采集FMC子卡-高速数据采集专家

FMC128是一款8通道250MHz采样率16位分辨率AD采集FMC子卡,符合VITA57.1规范,可以作为一个理想的IO模块耦合至FPGA前端,8通道AD将模拟信号数字化后通过高带宽的FMC连接器(HPC)连接至FPGA,从而大大降低了系统信…

电力智能运维是什么?有哪些优势?

设备检修维护是指对设备和系统进行必要的监视、维修和养护,通过日常的维护使设备保持良好的状态,确保设备安全、稳定、经济运行。由于时代的变迁,电力设备的检测维修变得也越来越智能化。采用的智能运维系统,可以更好的监控电力设…

BCSP-玄子Java开发之Java Web编程CH01_初识动态网页

BCSP-玄子Java开发之Java Web编程CH01_初识动态网页 1.1 B/S架构 B/S架构:浏览器/服务器 程序完全部署在服务器上使用浏览器访问服务器无需单独安装客户端软件 为什么要使用B/S架构 B/S与C/S比较B/S架构C/S架构软件安装浏览器需要专门的客户端应用升级维护客户…

NGINX PHP Cookie 会话中 PHPSESSID 缺少 HTTPOnly、Secure 属性解决方案

NGINX & PHP Cookie 会话中 PHPSESSID 缺少 HTTPOnly、Secure 属性解决方案 1 / 说明 基于安全的考虑,需要给cookie加上Secure和HttpOnly属性,HttpOnly比较好理解,设置HttpOnlytrue的cookie不能被js获取到,无法用document.coo…

linux系统的文件等相关操作命令

文章目录 1 查找文件(find、grep)2 查看文件内容(cat、more、less、head、tail)3 文件比较(diff)4 文本编辑器(vi、vim)5 文件压缩与解压(tar、tar.tgz、zip、rar、rar.g…

yum安装 lnmp

目录 一.nginx 的yum安装 1.关闭防火墙 2. 安装 nginx 3.安装依赖包 4.启动服务 二. 安装 mysql 5.7 (mariadb) 1.nysal的yum安装 2. 启动服务 3.在日志文件中找出root用户的初始密码 4.登录 mysql 5. 停止版本更新,稳定数据库的运行 三.php 的yum安装 1.…

rust abc(4): 定义变量并使用 mut 关键字

文章目录 1. 目的2. 不可变变量 (immutable variable)2.1 含义2.2 代码实例 3. 可变变量 (mutable variable)3.1 含义3.2 代码实例 4. 总结 1. 目的 学习 rust 语言中变量的定义方式, 包括普通变量(immutable)、可变变量(mutable…

轻量云服务器(香港)ping不通怎么解决?

​  在使用轻量云服务器(香港)时,有时候会出现ping不通的情况,这时候我们该怎么办呢? 首先,我们需要知道 ping 不通的原因。 ping 是一种基于 ICMP 协议的网络测试工具,它可以用来测试网络连接的质量和速度。如果 ping 不通&am…

英特尔进军晶圆代工,台积电“危”?

近来,半导体市场再次变得繁荣,尤其随着AI大型机模型的出现,半导体巨头们纷纷加大投资力度,以期在AI时代中积蓄新的增长。 作为AI大模型时代中最受益的厂商之一,英伟达稳居市场前沿,而AMD也加入了竞争&…

阿里发布2023年Java社招岗(正式版)面试题

每年的金三银四、金九银十都是各大公司招聘程序员的最佳时期,在这段时间内有好多程序员为面试而发愁,不知道如何才能收到好的 offer,拿到理想的薪资,实现自我的人生价值! 我想告诉大家的是,其实都不用愁的…

Web Worker是什么?怎么用?

71. Web Worker是什么?怎么用? Web Worker 是一种浏览器提供的 JavaScript 特性,它允许在后台线程中运行脚本,从而避免阻塞主线程并提高页面性能和响应速度。 1. Web Worker 的使用方法如下: 创建 Worker 对象&…

chatgpt赋能python:Python编译成库的利与弊

Python编译成库的利与弊 Python作为一种高级编程语言,具有简洁易读的语法和强大的生态系统,在数据科学、Web开发、游戏开发等领域得到广泛应用。然而,Python解释器的执行效率较低,因此为了提高Python程序的性能,常使用…

【嵌入式环境下linux内核及驱动学习笔记-(18)内核驱动模块的启动机制】

目录 1、module_init宏1.1 展开1.2 解释以下几个标识1.2.1 fn1.2.2 id1.2.3 类型 initcall_t :1.2.4 __used1.2.5 __init1.2.6 __attribute__ 1.3 实例说明 2、 驱动启动机制2.1 initcall_t 类型的数组2.2.1 __initcallx_start数组2.2.2 initcall_levels[]数组 2.3 …

每日一练 | 华为认证真题练习Day64

1、如下图所示的网络,所有路由器运行0SPF协议,链路上方为Cost值的大小,则RA路由表中到达网络10.0.0.0/8的Cost值是多少? A. 70 B. 20 C. 60 D. 100 2、如下图所示的网络,主机A没有配置网关,主机B存在网关…

基于GEC6818 Qt智能病房监控系统

文章目录 一、项目设备及平台二、项目功能说明1. 整体功能2. GEC6818开发板功能介绍3. GY39模块功能介绍4. MQ-2型烟雾传感器功能介绍5. RFID模块 三、硬件系统设计实现与图表四、软件系统设计实现与流程图1. 软件系统设计总体描述2. 软件实现流程图3. 操作过程 五、调试过程中…

基于电容电流前馈与电网电压全前馈的单相LCL并网逆变器谐波抑制MATLAB仿真(电压比例反馈及一二次微分反馈)

基于电容电流前馈与电网电压全前馈的单相LCL并网逆变器谐波抑制MATLAB仿真(电压比例反馈及一二次微分反馈)资源-CSDN文库https://download.csdn.net/download/weixin_56691527/87941037模型简介: 参考阮新波教授【LCL型并网逆变器的控制技术…

scrapy的数据保存到数据库

将数据保存到数据库 mysql数据库 下载链接数据库的依赖 Conda/pip install pymysql在piplines.py 文件中 重写open_spider方法 ​ 连接到mysql数据库 def open_spider(self, spider):self.conn pymysql.Connect(hostlocalhost,port3306,userroot,password20020115,dbscrap…

go系列-读取文件

1 概述 2 整个文件读入内存 直接将数据直接读取入内存,是效率最高的一种方式,但此种方式,仅适用于小文件,对于大文件,则不适合,因为比较浪费内存。 2.1 直接指定文化名读取 在 Go 1.16 开始,i…