美文网首页
(八)多进程爬虫

(八)多进程爬虫

作者: 交易狗二哈 | 来源:发表于2017-03-24 20:43 被阅读189次

    一、并发爬取数据

    当我们需要爬取的 url 链接非常多的时候,用 for 循环对所有链接进行访问显然是非常耗时的。
    怎么提高爬虫效率呢?
    我们可以使用并发来对URL进行访问以爬取数据。
    有以下三种并发方式

    • 多线程(threading)
    • 多进程(multiprocessing)
    • 协程(gevent)

    先来试试多进程

    二、 多线程example

    import requests
    import time
    from multiprocessing.dummy import Pool
    
    def get_url(url):
        html = requests.get(url)
        #print(html.url)
    
    urls = ["http://www.mmjpg.com/home/{}".format(i) for i in range(1,40)]
    
    time1 = time.time()
    for url in urls:
        get_url(url)
    time2 = time.time()
    print('单线程耗时' + str(time2 - time1))
    
    pool = Pool(4)
    time3 = time.time()
    results = pool.map(get_url, urls)
    pool.close()
    pool.join()
    time4 = time.time()
    print('多线程耗时' + str(time4 - time3))
    

    先来试试请求 40 个网页分别的耗时

    >>> 
    =================== RESTART: E:\Python项目\爬阿爬\多线程,进程\多进程.py ===================
    单线程耗时3.8298497200012207
    多线程耗时3.5330474376678467
    

    差别不是太大,但请求100呢。把 range 的范围改到 100,再运行试试

    =================== RESTART: E:\Python项目\爬阿爬\多线程,进程\多进程.py ===================
    单线程耗时16.267414093017578
    多线程耗时4.5447304248809814
    >>> 
    

    差距已经很大了

    三、多线程爬取

    我们以爬取 实验楼 的课程为例。


    分析下url,可以发现改变 page 的参数就可以切换页数了,那么共有几页呢,我们只需爬取页面下方的这个系列的数值,倒二个就是最大的页面数。
    代码如下

    >>> link = 'https://www.shiyanlou.com/courses/?course_type=all&tag=all&fee=all&page=1'
    >>> r = requests.get(link)
    >>> bs0bj = BeautifulSoup(r.text, 'lxml')
    >>> pages = bs0bj.select('body > div.container.layout-hasside.layout-margin-top > div.row > div.col-md-9.layout-body > div.content.position-relative > nav > ul > li')
    >>> page = int(pages[-2].text.strip())
    >>> print('共{}页'.format(page))
    共24页
    

    我们来爬取所有课程的名称 title, 说明 introduce ,热度 num。
    如果要爬取别的课程只需改下 url 的 tag 参数就行



    总的代码如下

    import requests
    from bs4 import BeautifulSoup
    from multiprocessing.dummy import Pool
    
    def get_html(page):
        url = 'https://www.shiyanlou.com/courses/?course_type=all&tag=all&fee=all&page={}'.format(page)
        print('第{}页'.format(page))
        html = requests.get(url)
        soup = BeautifulSoup(html.text, 'lxml')
        
        titles = soup.find_all(class_='course-name')
        introduces = soup.find_all(class_='course-desc')
        nums = soup.find_all(class_='course-per-num pull-left')
    
        for title, num, introduce in zip(titles, nums, introduces):
            data = {
                'title'     :   title.get_text(),
                'num'       :   num.get_text().strip(),
                'introduce' :   introduce.get_text()
                }
            print(data)
    
    
    if __name__ == '__main__':
        link = 'https://www.shiyanlou.com/courses/?course_type=all&tag=all&fee=all&page=1'
        r = requests.get(link)
        bs0bj = BeautifulSoup(r.text, 'lxml')
        pages = bs0bj.select('body > div.container.layout-hasside.layout-margin-top > div.row > div.col-md-9.layout-body > div.content.position-relative > nav > ul > li')
        page = int(pages[-2].text.strip())
        print('共{}页'.format(page))
        pool = Pool(4)
        pool.map(get_html, range(1, page+1))
        #pool.map_async(get_html, range(1, page+1))
        #for i in range(page+1):
            #pool.apply(func=get_html, args=(i,))
        pool.close()
        pool.join()
    

    运行下试试看

    >>> 
    ================== RESTART: C:\Users\Why Me\Desktop\爬实验楼.py ==================
    共24页
    第1页第3页第5页第7页
    
    
    
    {'num': '536', 'introduce': '本课将介绍 json 和一些常见的 json 库,并用 C++ 编写一个 json 生成器,生成 json 数据,并学习编写测试用例。', 'title': 'C++ 编写 json 生成器'}{'num': '112', 'introduce': '本训练营主要讲后门技术实战,偏重于渗透成功后的维持访问。该课程共包含 10 个实验,每个实验都提供详细的步骤和截图,其中会有专门的三节实验,专门用来讲解木马的制作,以及对生成的后门木马的源码分析 。', 'title': 'Kali 渗透测试 - 后门技术实战(10个实验)'}
    
    {'num': '467', 'introduce': '在这个人人自拍的年代,每个人的智能手机中至少都装了一款美颜相机或者美图软件,而这些软件实现美图功能又主要是靠滤镜来实现的。而这门课程将带领大家使用 Python 编写一个简单的滤镜程序。', 'title': 'Python 实现简单滤镜'}{'num': '1381', 'introduce': '出租车是我们生活中经常乘坐的一种交通工具,但打车难的问题也限制了我们更好地利用这种交通方式。在哪些地方出租车更容易打到?在什么时候更容易打到出租车?本课程将基于某市的出租车行驶轨迹数据,带你学习如何应用Spark SQL和机器学习相关技巧,并且通过数据可视化手段展现分析结果。', 'title': '大数据带你挖掘打车的秘籍'}
    ...
    ...
    
    前面用的是 multiprocessing.dummy import Pool,因为不知道是我电脑的原因还是什么,一般应该multiprocessingimport Pool就行了

    相关文章

      网友评论

          本文标题:(八)多进程爬虫

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