php多线程抓取多个网页(小白:多线程便携的数据使用流程及常用方法 )

优采云 发布时间: 2021-09-22 00:20

  php多线程抓取多个网页(小白:多线程便携的数据使用流程及常用方法

)

  修剪小白色,最近被一位高手的B站学习,这里,请,请“

  运行结果:

  

  

  1:多线程:CPU密集型程序适用于多线程,您可以充分利用计算机的多核,通常使用单线程采集数据较慢,多线程是多个行执行的任务返回这个过程

  穿线模块==============================“”“”“线程模块

  使用过程:

  t =线程(目标=事件函数名称)

  t.start()

  t.join()#块等待线程以避免堵塞线程生成

  多线程应用方案:

  io操作更多程序,包括网络IO,本地磁盘IO

  Reptral部分请求响应:网络IO

  爬网程序处理的重新启动:本地磁盘IO

  因此,使用多线程*敏*感*词*爬行动物可以提高抓取数据的效率

  2:队列:当多个进程执行任务时,它易于阻止,数据无法确定数据,因此队列解决了此问题,使用

  将数据放入队列中。

  在提取

  fromqueue import queue

  通用方法:

  创建队列q = queue()

  进入队列:q.put()

  导出:q.get()

  确定队列是否为空:q.empty()

  关闭解决方案时为空值:

  ·q.get(block = true,timeout = 2) @ @ jdeast延迟时间2秒后2秒,

  ·.get(block = false)

  ·虽然不是q.empty():

  q.get()

  3:线程锁:当多个线程操作相同的共享资源时,当在下面的时间启动其中一个进程时,不会阻止锁定。

  履带:

  这个爬行是腾讯招募,攀登工作岗位的具体信息,总共有两个页面

  

  

  想法

  获得两页,您可以发现第一个需要更改是我们需要找到的位置,第二个是PageIndex是页数,第二个横向跳转是唯一的变量PostId,只需要提取物POSTID作为第一页中第二页的POSTID。这将获得两个页面信息。

  在第一页中,获取POSTID,准备跳转链接,并在第二页中获取作业信息。其中,需要两个队列和2个线程锁,页面应该是队列和线程锁定

  代码:

  定义连接,队列,线程锁定

  def __init__(self):

self.one_q=Queue()#队列1

self.two_q=Queue()#队列2

self.one_lock=Lock()#锁1

self.two_lock=Lock()#锁2

self.number=0

self.one_url='https://careers.tencent.com/tencentcareer/api/post/Query?timestamp=1630301002746&countryId=&cityId=&bgIds=&productId=&categoryId=&parentCategoryId=&attrId=&keyword={}&pageIndex={}&pageSize=10&language=zh-cn&area=cn'

self.two_url='https://careers.tencent.com/tencentcareer/api/post/ByPostId?timestamp=1630388009179&postId={}&language=zh-cn'

self.headers={

'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36'

}

  首次访问需要输入队列,Word是可以手动输入的作业名称,URllib.parse.quote(kw)将输入的汉字转到计算机可识别的编码,总= self.get_total(Word)是一个自定义的功能,当未确认页数以及完全连接时,自动获取帖子中的页数。 self.one_q.put(one_url)将在队列中连接

  def url_in(self):

kw=input('请输入想查找的职位:')

word=urllib.parse.quote(kw)

total=self.get_total(word)

for pageindex in range(1,total+1):

one_url=self.one_url.format(word,pageindex)

self.one_q.put(one_url)

  此代码写入上面的总功能,页数

  def get_total(self,word):

one_url=self.one_url.format(word,1)

html=requests.get(url=one_url,headers=headers).json()

count=html['Data']['Count']

total=count//10 if count==0 else count//10+1

print(total)

return total

  接下来解析连接以获取POSTID,完成链接到跳转页面,线程锁定内部,但锁将打开下一个进程,只要队列不为空,请携带链接,然后分析,如果它是空的,退出

  def one_parse(self):

while True:

self.one_lock.acquire() #避免多个线程判断一个队列,锁了

if not self.one_q.empty():

one_url=self.one_q.get()

self.one_lock.release()#开锁

html=requests.get(url=one_url,headers=self.headers).json()

rep=html['Data']['Posts']

for i in rep:

post_id=i['PostId']

URL=self.two_url.format(post_id)。#完成需要的二级链接

#给二级队列

self.two_q.put(URL)

#print(URL)

else:

self.one_lock.release()

break

  有必要强调,每当放置队列时,最初需要写入使用的功能,但在队列之后,def括号内的使用对象都在队列中,无需写入,默认自我

  下一个是得到第二页=====“主要所需作业的主要信息

   def two_parse(self):

while True:

try:

self.two_lock.acquire()

URL=self.two_q.get(timeout=3) #一级页面和二级页面容易冲突,时间延迟等一级页面首先完成

self.two_lock.release()

html=requests.get(url=URL,headers=self.headers).json()

item={}

item['name']=html['Data']['RecruitPostName']

item['typ']=html['Data']['CategoryName']

item['add']=html['Data']['LocationName']

item['req']=html['Data']['Requirement']

item['duty']=html['Data']['Responsibility']

self.two_lock.acquire()

self.number+=1

self.two_lock.release()

print(item)

except Exception as e:

self.two_lock.release()

break

  最后,使用直接多线程,将两个队列放入两个线程可以运行

   def run(self):

self.url_in()

#创建多线程

t1_list=[]

t2_list=[]

for i in range(2):

t1=Thread(target=self.one_parse)

t1_list.append(t1)

t1.start()

for i in range(2):

t2=Thread(target=self.two_parse)

t2_list.append(t2)

t2.start()

for t1 in t1_list:

t1.join()

for t2 in t2_list:

t2.join()

  完成代码

  '''多级页面的多线程---腾讯招聘'''

import requests

from threading import Thread,Lock

from queue import Queue

import urllib.parse

import json,time

class Tenxun():

def __init__(self):

self.one_q=Queue()

self.two_q=Queue()

self.one_lock=Lock()

self.two_lock=Lock()

self.number=0

self.one_url='https://careers.tencent.com/tencentcareer/api/post/Query?timestamp=1630301002746&countryId=&cityId=&bgIds=&productId=&categoryId=&parentCategoryId=&attrId=&keyword={}&pageIndex={}&pageSize=10&language=zh-cn&area=cn'

self.two_url='https://careers.tencent.com/tencentcareer/api/post/ByPostId?timestamp=1630388009179&postId={}&language=zh-cn'

self.headers={

'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36'

}

def url_in(self):

kw=input('请输入想查找的职位:')

word=urllib.parse.quote(kw)

total=self.get_total(word)

for pageindex in range(1,total+1):

one_url=self.one_url.format(word,pageindex)

self.one_q.put(one_url)

def get_total(self,word):

one_url=self.one_url.format(word,1)

html=requests.get(url=one_url,headers=headers).json()

count=html['Data']['Count']

total=count//10 if count==0 else count//10+1

print(total)

return total

def one_parse(self):

while True:

self.one_lock.acquire() #避免多个线程判断一个队列,锁了

if not self.one_q.empty():

one_url=self.one_q.get()

self.one_lock.release()

html=requests.get(url=one_url,headers=self.headers).json()

rep=html['Data']['Posts']

for i in rep:

post_id=i['PostId']

URL=self.two_url.format(post_id)

#给二级队列

self.two_q.put(URL)

#print(URL)

else:

self.one_lock.release()

break

def two_parse(self):

while True:

try:

self.two_lock.acquire()

URL=self.two_q.get(timeout=3) #一级页面和二级页面容易冲突,时间延迟等一级页面首先完成

self.two_lock.release()

html=requests.get(url=URL,headers=self.headers).json()

item={}

item['name']=html['Data']['RecruitPostName']

item['typ']=html['Data']['CategoryName']

item['add']=html['Data']['LocationName']

item['req']=html['Data']['Requirement']

item['duty']=html['Data']['Responsibility']

self.two_lock.acquire()

self.number+=1

self.two_lock.release()

print(item)

except Exception as e:

self.two_lock.release()

break

def run(self):

self.url_in()

#创建多线程

t1_list=[]

t2_list=[]

for i in range(2):

t1=Thread(target=self.one_parse)

t1_list.append(t1)

t1.start()

for i in range(2):

t2=Thread(target=self.two_parse)

t2_list.append(t2)

t2.start()

for t1 in t1_list:

t1.join()

for t2 in t2_list:

t2.join()

if __name__=="__main__":

start_time=time.time()

spider=Tenxun()

spider.run()

end_time=time.time()

print('time:%.2f'%(end_time-start_time))

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线