挑灯看花 发表于 2020-7-19 21:54

python多线程求助(已解决)

本帖最后由 挑灯看花 于 2020-7-20 09:01 编辑

本人想编写一个多线程爬虫,利用queue模块。
每次从queue里取一个url,但是爬取需要时间,造成了多个线程取同一个ur,请问怎么解决{:301_972:}l

518 发表于 2020-7-19 21:58

爬之前pop掉可行吗

bluerabbit 发表于 2020-7-19 22:01

get 怎么会取到同一个元素呢?楼主的程序贴出来看一下

挑灯看花 发表于 2020-7-19 22:01

518 发表于 2020-7-19 21:58
爬之前pop掉可行吗

这样会导致最后几个url没爬完主线程就结束了{:301_1009:}

涛之雨 发表于 2020-7-19 22:02

可以对爬取的线程进行分配,比如4个线程,每一个线程负责独立的页数
最后处理的时候可以判断总爬取的数量是否等于总数

塞北的雪 发表于 2020-7-19 22:04

从队列里取出一个就删除一个,或者弄个flag,标记运行中

挑灯看花 发表于 2020-7-19 22:06

本帖最后由 挑灯看花 于 2020-7-19 22:14 编辑

bluerabbit 发表于 2020-7-19 22:01
get 怎么会取到同一个元素呢?楼主的程序贴出来看一下
class get_video_content(get_video_time,get_user_id):
    def __init__(self,class_id,course_id):
      self.course_id = course_id
      self.class_id = class_id
      get_user_id.__init__(self)
      self.ts = get_timestamp()
      self.url_get_video_content = "".format(course_id)
      self.params_get_video_content = json.dumps({"class_id":class_id})
      self.headers_get_video_content ={""
}

      self.cookies = get_cookies()
      self.video_list = []
      self.parse_get_video_list()
      self.video_list_queue = Queue()
      for video_id in self.video_list:
            # get_video_time.__init__(self,course_id,class_id,video_id,self.user_id)
            self.video_list_queue.put(video_id)
      
      self.list_thread = [] #进行多线程部分,其他不重要
      for i in range(5):
            t = threading.Thread(target = self.run_video_queue)
            self.list_thread.append(t)

      for t in self.list_thread:
            t.setDaemon(True)
            t.start()
      self.video_list_queue.join()
            
    def run_video_queue(self):
      while True:
            video_id = self.video_list_queue.get()
            get_video_time.__init__(self,self.course_id,self.class_id,video_id,self.user_id)
            self.video_list_queue.task_done()
   
    def parse_get_video_list(self):
      r = requests.post(self.url_get_video_content,headers = self.headers_get_video_content,cookies = self.cookies,data = self.params_get_video_content)
      r = json.loads(r.content.decode())
      for x in r["coursewareArray"]:
            try:
                video_id = x["children"]["items"]["item_id"]
                video_complete = x["done"]
                if not video_complete:
                  self.video_list.append(video_id)
            except:
                pass
代码写的比较烂{:301_1004:}

删掉丶关于n1 发表于 2020-7-19 23:32

可以设置锁呀 threading.Lock()做一个def Get_url(self)

    if video_list_lock.acquire(True):# 获得锁

      video_list_queue.get()

       video_list_lock_lock.release()# 释放所

JokerX 发表于 2020-7-19 23:33

大概这样
cnt = 0

def fun(foo):
    pass
    global cnt
    cnt += 1


threading.Thread(target=fun, args=(16, )).start()
threading.Thread(target=fun, args=(17, )).start()
threading.Thread(target=fun, args=(18, )).start()
threading.Thread(target=fun, args=(19, )).start()


while cnt != 4:
    pass

xccxvb 发表于 2020-7-19 23:46

直接用pop就可以了吧,queue为空会自动阻塞的
页: [1] 2
查看完整版本: python多线程求助(已解决)