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

news/2024/7/19 11:12:07 标签: python, 算法, 爬虫, 网络爬虫, 爬山算法
前言
最近有遇到很多私信让我讲一讲多进程的爬虫,我发现大家对爬虫的框架写法和进程的理解有很多的问题和疑问,这次就带来一个小实战让大家理解多进程爬虫以及框架的写法

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

📝个人主页→数据挖掘博主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就直接有数据了,所以是可以直接抓的如下图:

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

python">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或者正则表达式都可以,看你喜欢,我这里提供代码给大家参考,由于只是为了讲解就只爬取品牌和价格其他的东西你们喜欢可以自己加,代码如下:

python">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)

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

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

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

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

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


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


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


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

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

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

python">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.niftyadmin.cn/n/467546.html

相关文章

无需麻烦,快速下载MySQL JDBC驱动程序!

如何提升你的MySQL数据库操作速度呢? 不必再费时寻找,我讲为你带来最简便、快速的MySQL JDBC驱动程序下载方法! 无需繁琐步骤,轻松获取所需,让你的数据库操作更加流畅,事半功倍!立即点击下载即…

【软考网络管理员】2023年软考网管初级常见知识考点(8)-广域网技术

涉及知识点 广域网交换方式,广域网流量控制,广域网链路层协议,广域网传输标准,软考网络管理员常考知识点,软考网络管理员网络安全,网络管理员考点汇总。 原创于:CSDN博主-《拄杖盲学轻声码》&a…

【Leetcode60天带刷】day35——452. 用最少数量的箭引爆气球,435. 无重叠区间,763.划分字母区间

​ 题目: 452. 用最少数量的箭引爆气球 有一些球形气球贴在一堵用 XY 平面表示的墙面上。墙面上的气球记录在整数数组 points ,其中points[i] [xstart, xend] 表示水平直径在 xstart 和 xend之间的气球。你不知道气球的确切 y 坐标。 一支弓箭可以沿着…

chatgpt赋能python:Python编写n!——让阶乘计算变得更简单

Python编写n!——让阶乘计算变得更简单 阶乘是高中数学中常见的运算,它的含义是从1到n的所有正整数相乘,用叹号表示为n!。例如,5! 1 2 3 4 5 120。在计算机编程中,我们常常需要计算阶乘。而Python作为一门便捷易用的编程语…

2.3、Bean的管理

一、Bean的装配(IOC应用实现) 创建应用组件之间的协作的行为通常称为装配(wiring)。Spring IOC通过应用上下文(ApplicationContext)装载Bean的定义并把他们组装起来。 Spring应用上下文(Applica…

chatgpt赋能python:Python编写预警系统——保障企业安全的得力工具

Python编写预警系统——保障企业安全的得力工具 随着互联网应用的发展,企业所要面对的风险和威胁也与日俱增,预警系统的作用在保障企业安全中越来越显著。Python编写预警系统,成为了许多企业和团队的首选,具有方便快捷、灵活多样…

【软考网络管理员】2023年软考网管初级常见知识考点(10)- 网际协议IP及IPV6,IPV4详解

涉及知识点 分类的IP地址,子网划分,CIDR和路由汇聚,IPV4数据报格式,IPV6协议,软考网络管理员常考知识点,软考网络管理员网络安全,网络管理员考点汇总。 原创于:CSDN博主-《拄杖盲学…

k8s 学习九,pod 知识点 上

在 K8S 中, pod 是一个非常关键的存在,我们一起来看看 pod 具体是个什么? pod 是个啥? pod 是个什么呢?pod 是 K8S中的一个核心概念 每一个 pod 都会有一个特殊的根容器,叫做 pause 容器,paus…