(八)多进程爬虫

一、并发爬取数据

当我们需要爬取的 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就行了
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容