php多线程抓取多个网页(爬虫所需技术及准备事项代码如下run_函数)

优采云 发布时间: 2021-10-26 22:04

  php多线程抓取多个网页(爬虫所需技术及准备事项代码如下run_函数)

  爬虫主要的运行时间消耗是请求一个网页时的io阻塞,所以开启多个线程,让不同的请求同时等待可以大大提高爬虫的运行效率。

  本文基于多线程(这里开了10个线程),使用github的api,抓取所有fork cpython项目的5000多个项目信息,并将数据存储在一个json文件中。

  抓取github的这个内容,在之前的文章文章中,展示了没有使用多线程的版本,这里是直接在此基础上的改进。

  爬虫需要的技术和准备

  爬虫代码如下

  import requests

import time

from threading import Thread

from queue import Queue

import json

def run_time(func):

def wrapper(*args, **kw):

start = time.time()

func(*args, **kw)

end = time.time()

print('running', end-start, 's')

return wrapper

class Spider():

def __init__(self):

self.qurl = Queue()

self.data = list()

self.email = '' # 登录github用的邮箱

self.password = '' # 登录github用的密码

self.page_num = 171

self.thread_num = 10

def produce_url(self):

baseurl = 'https://api.github.com/repos/python/cpython/forks?page={}'

for i in range(1, self.page_num + 1):

url = baseurl.format(i)

self.qurl.put(url) # 生成URL存入队列,等待其他线程提取

def get_info(self):

while not self.qurl.empty(): # 保证url遍历结束后能退出线程

url = self.qurl.get() # 从队列中获取URL

print('crawling', url)

req = requests.get(url, auth = (self.email, self.password))

data = req.json()

for datai in data:

result = {

'project_name': datai['full_name'],

'project_url': datai['html_url'],

'project_api_url': datai['url'],

'star_count': datai['stargazers_count']

}

self.data.append(result)

@run_time

def run(self):

self.produce_url()

ths = []

for _ in range(self.thread_num):

th = Thread(target=self.get_info)

th.start()

ths.append(th)

for th in ths:

th.join()

s = json.dumps(self.data, ensure_ascii=False, indent=4)

with open('github_thread.json', 'w', encoding='utf-8') as f:

f.write(s)

print('Data crawling is finished.')

if __name__ == '__main__':

Spider().run()

  读者只需要在Spider的__init__中指定自己的github邮箱和密码即可运行爬虫。

  爬虫描述如下

  1.run_time函数是计算程序运行时间的装饰器,作用于Spider对象的run函数

  2.蜘蛛类

  爬虫结果

  爬取结果显示如下

  

  该程序启动 10 个线程以获取 171 页需要 33 秒。在这个文章中,不使用多线程,耗时333秒。为了对多线程效率的提升有更清晰的体验,读者可以尝试修改上面代码中的self.page_num和self.thread_num。

  我这里做了个实验,self.page_num的值设置为20,表示总共会抓取20个页面

  一个问题

  最后,留下一个问题供读者思考:在之前的文章中,我们也实现了多线程爬虫。为什么当时的代码这么简单,现在却变得复杂了许多?

  跟进

  下一篇多线程爬虫文章将在翻页和爬取二级页面时实现多线程。

  栏目信息

  专栏首页:python编程

  栏目目录:目录

  履带目录:履带系列目录

  版本说明:软件和软件包版本说明

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线