美文网首页大数据 爬虫Python AI Sql我的工作室
Python爬虫实战入门六:提高爬虫效率—并发爬取智联招聘

Python爬虫实战入门六:提高爬虫效率—并发爬取智联招聘

作者: Python编程社区 | 来源:发表于2018-08-31 11:41 被阅读11次

    之前文章中所介绍的爬虫都是对单个URL进行解析和爬取,url数量少不费时,但是如果我们需要爬取的网页url有成千上万或者更多,那怎么办?

    使用for循环对所有的url进行遍历访问?

    嗯,想法很好,但是如果url过多,爬取完所有的数据会不会太过于耗时了?

    对此我们可以使用并发来对URL进行访问以爬取数据。

    一般而言,在单机上我们使用三种并发方式:

    多线程(threading)

    多进程(multiprocessing)

    协程(gevent)

    对于以上三种方法的具体概念解释和说明,各位可以自行网上搜索了解,相信会比我解释得清楚,所以在此就不对它们进行解释说明了。

    本系列文章有两个重点,一个是实战,一个是入门,既为实战,理论性的东西就描述得比较少;既为入门,所讲述的都是简单易懂易操作的东西,高深的技术还请入门之后自行探索,那样也会成长得更快。

    那么下面,开始并发爬取的实战入门,以多进程为例,并发爬取智联招聘的招聘信息。

    一、分析URL和页面结构

    1、搜索全国范围内职位名包含“Python”的职位招聘

    我们不分职业类别、不分行业类别,工作地点选为全国,职位名为“Python”,对招聘信息进行搜索,结果如下图:

    我们注意图中三个红框的信息:

    搜索结果的url结构;(构造url地址进行for循环遍历)

    搜索结果的条数;(判断url的数量)

    采集的信息的主体;(解析数据)

    通过筛选url参数,我们确定了需要爬取的基本URL为:

    1http://sou.zhaopin.com/jobs/searchresult.ashx?jl=全国&kw=python&kt=3&p=2

    其中

    http://sou.zhaopin.com/jobs/searchresult.ashx

    为请求地址和目录

    jl:工作地点参数

    kw:搜索的关键字

    kt:以职位名搜索

    p:页数

    我们可以发现,除了页数会变化之外,其余的参数值都是固定的值。我们来确定一下搜索结果的总页数。

    因为网页上有提示一共有多少个职位满足条件,我们拿总职位数除以单页显示的职位数量即可知道搜索结果的页数。

    # coding:utf-8

    import requests

    from bs4 import BeautifulSoup

    import re

    url = 'http://sou.zhaopin.com/jobs/searchresult.ashx?jl=全国&kw=python&p=1&kt=3'

    wbdata = requests.get(url).content

    soup = BeautifulSoup(wbdata, 'lxml')

    items = soup.select("div#newlist_list_content_table > table")

    count = len(items) - 1

    # 每页职位信息数量

    print(count)

    job_count = re.findall(r"共(.*?)个职位满足条件", str(soup))[0]

    # 搜索结果页数

    pages = (int(job_count) // count) + 1

    print(pages)

    结果返回每页60条职位信息,一共有14页。

    那么我们的待爬取的url地址就有14个,url地址中参数p的值分别从1到14,这么少的url,使用for循环也可以很快完成,但在此我们使用多进程进行演示。

    二、在爬虫中使用多进程

    先上代码:

    # coding:utf-8

    import requests

    from bs4 import BeautifulSoup

    from multiprocessing import Pool

    def get_zhaopin(page):

        url = 'http://sou.zhaopin.com/jobs/searchresult.ashx?jl=全国&kw=python&p={0}&kt=3'.format(page)

        print("第{0}页".format(page))

        wbdata = requests.get(url).content

        soup = BeautifulSoup(wbdata,'lxml')

        job_name = soup.select("table.newlist > tr > td.zwmc > div > a")

        salarys = soup.select("table.newlist > tr > td.zwyx")

        locations = soup.select("table.newlist > tr > td.gzdd")

        times = soup.select("table.newlist > tr > td.gxsj > span")

        for name, salary, location, time in zip(job_name, salarys, locations, times):

            data = {

                'name': name.get_text(),

                'salary': salary.get_text(),

                'location': location.get_text(),

                'time': time.get_text(),

            }

            print(data)

    if __name__ == '__main__':

        pool = Pool(processes=2)

        pool.map_async(get_zhaopin,range(1,pages+1))

        pool.close()

        pool.join()

    结果如下:

    因为除了使用了多进程之外,其他的代码与之前文章介绍的方法大同小异,所以在此只介绍一下多进程的核心代码:

    1from multiprocessing import Pool

    multiprocessing是Python自带的一个多进程模块,在此我们使用其Pool方法。

    if __name__ == '__main__':

        pool = Pool(processes=2)

        pool.map_async(get_zhaopin,range(1,pages+1))

        pool.close()

        pool.join()

    实例化一个进程池,设置进程为2;

    调用进程池的map_async()方法,接收一个函数(爬虫函数)和一个列表(url列表)

    如此,在爬虫中使用多进程进行并发爬取就搞定了,更多高级、复杂强大的方法,还请各位参考其他文档资料。

    如果你也也在学习Python,推荐你关系下我的微信公众号:Python学习部落,更多资源与教程与你共享。

    相关文章

      网友评论

        本文标题:Python爬虫实战入门六:提高爬虫效率—并发爬取智联招聘

        本文链接:https://www.haomeiwen.com/subject/lsdswftx.html