鱼C论坛

 找回密码
 立即注册
查看: 2069|回复: 3

[已解决]python多线程爬取,不等子线程完成,主线程就结束了

[复制链接]
发表于 2020-10-25 17:30:42 | 显示全部楼层 |阅读模式
50鱼币
本帖最后由 景暄 于 2020-10-25 17:39 编辑

爬取糗事百科的段子,可能是join()函数设置的有问题,每次运行都没报错,但也没把结果打印出来

  1. from threading import Thread
  2. from queue import Queue
  3. from fake_useragent import UserAgent
  4. import requests
  5. from lxml import etree

  6. #爬虫类
  7. class CrawlInfo(Thread):
  8.     def __init__(self,url_queue,html_queue):
  9.         Thread.__init__(self)
  10.         self.url_queue = url_queue
  11.         self.html_queue = html_queue
  12.     def run(self):
  13.         headers = {
  14.             'User-Agent':UserAgent().random
  15.         }
  16.         while self.url_queue.empty() == False:
  17.             url = self.url_queue.get()
  18.             response = requests.get(url, headers=headers)
  19.             if response.status_code == 200:
  20.                 self.html_queue.put(response.text)

  21. #解析类
  22. class ParseInfo(Thread):
  23.     def __init__(self, html_queue):
  24.         Thread.__init__(self)
  25.         self.html_queue  = html_queue

  26.     def run(self):
  27.         while self.html_queue.empty() == False:
  28.             e = etree.HTML(self.html_queue.get())
  29.             span_contents = e.xpath('//div[@class="content"]/sapn[1]')
  30.             for span in span_contents:
  31.                 info = span.xpath('string(.)')
  32.                 print(info)

  33. if __name__ == '__main__':
  34.     # 存储url的容器
  35.     url_queue = Queue()
  36.     #存储内容的容器
  37.     html_queue = Queue()
  38.     base_url = 'https://www.qiushibaike.com/text/page/{}/'
  39.     for i in range(1, 14):
  40.         new_url = base_url.format(i)
  41.         url_queue.put(new_url)
  42.     #创建一个爬虫
  43.     crawl_list = []
  44.     for i in range(0, 3):
  45.         crawl1 = CrawlInfo(url_queue, html_queue)
  46.         crawl_list.append(crawl1)
  47.         crawl1.start()

  48.     for crawl in crawl_list:
  49.         crawl.join()

  50.     parse = ParseInfo(html_queue)
  51.     parse.start()
复制代码
最佳答案
2020-10-25 17:30:43
多线程爬一个不可描述网站
  1. import requests
  2. import bs4
  3. import time
  4. import os,sys
  5. import random
  6. from threading import Thread
  7. import re

  8. def down_jpg(url1,numm):
  9.     headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36',
  10.                
  11.                'referer':'newurl',
  12.                'cookie':'__cfduid=dccf7de8219a41296cc717949a14788851601881784; existmag=mag; 4fJN_2132_saltkey=aU1VYvxu; 4fJN_2132_lastvisit=1601882439; 4fJN_2132_visitedfid=36D2; PHPSESSID=6be8caov3lgjr4dhlsq9bm7rm7; 4fJN_2132_st_p=0%7C1602987046%7C5bc121f439bbf8cfe7e3512e0335a580; 4fJN_2132_viewid=tid_2117; 4fJN_2132_sid=IBh6Aq; 4fJN_2132_sendmail=1; 4fJN_2132_lastact=1602987586%09forum.php%09forumdisplay; 4fJN_2132_st_t=0%7C1602987586%7C88bfb33921f3da072fadcaf37c081bc4; 4fJN_2132_forum_lastvisit=D_2_1602946097D_36_1602987586'
  13.                ,"Connection": "close"
  14.                }
  15.     re = requests.get(url1,headers = headers)
  16.     img = re.content
  17.     print('downlond jpg',url1)
  18.     name = os.listdir()
  19.     for i in name:
  20.         if i !='http.txt' and i[-3:-1] =='tx':
  21.             name1 = name[0]+str(numm)+'1'
  22.     with open(name1+'.jpg','wb')as f:
  23.         f.write(img)

  24. def jpg_list(listy):
  25.     plist = []
  26.     num = len(listy)
  27.     for i in range(num):
  28.         t = Thread(target = down_jpg,args = (listy[i],i))
  29.         t.start()
  30.         plist.append(t)
  31.     for i in plist:
  32.         i.join()
  33.         print('图',i,'完成')
  34.     print('------over------')
  35.     time.sleep(10)
  36.    

  37. def find_new(res2,newurl):
  38.     num = 0
  39.     soup = bs4.BeautifulSoup(res2.text,'html.parser')
  40.     aaa = soup.find_all(onload='thumbImg(this)')
  41.     print('jpg...')
  42.     with open('http.txt','w',encoding='utf-8')as f:
  43.         f.write(soup.text)
  44.     listy = []
  45.     numy = 0
  46.     for i in aaa:
  47.         x = i.get('src')
  48.         listy.append(x)

  49.     jpg_list(listy)

  50.             

  51. def open_new(ilist):
  52.     headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36',
  53.                
  54.                'referer':url,
  55.                'cookie':'自己添加'
  56.                }
  57.     global newurl
  58.     newurl = 'https://www.busfan.cloud/forum/'+ilist
  59.     res2 = requests.get(newurl,headers = headers)
  60.     code = res2.status_code
  61.     if code ==200:
  62.         print('子页面连接成功',newurl)
  63.         time.sleep(random.randint(1,3))
  64.         soup = bs4.BeautifulSoup(res2.text,'html.parser')
  65.         print('txt...')
  66.         name0 = os.getcwd()
  67.         name = re.findall("[\u4e00-\u9fa5]+",name0)   
  68.         find_new(res2,newurl)
  69.     else:
  70.         print('打不开')


  71.         
  72. def find_data(res):
  73.     print('解析主页拿到子页面地址和名称')
  74.     zlist = []
  75.     pathlist = []
  76.     soup = bs4.BeautifulSoup(res.text,'html.parser')
  77.     aaa = soup.find_all(onclick = 'atarget(this)')
  78.     for new in aaa:
  79.         ilist = new.get('href')#子页面地址
  80.         name = new.text   #子页面名称
  81.         print('得到:',name)
  82.         path = 'M:\\3\\'+name
  83.         os.chdir('M:\\3')
  84.         lj = os.listdir()
  85.         for xi in lj:
  86.             if name == xi:
  87.                 print('删除重复文件夹',xi)
  88.                 os.chdir(path)
  89.                 file = os.listdir()
  90.                 for zi in file:
  91.                     os.remove(zi)
  92.                 os.chdir('M:\\3')
  93.                 os.rmdir(path)
  94.         
  95.         zlist.append(ilist)
  96.         pathlist.append(path)

  97.     num = len(zlist)
  98.     for i in range(num):
  99.         t = Thread(target = open_new,args = (zlist[i],))
  100.         os.mkdir(pathlist[i])
  101.         os.chdir(pathlist[i])
  102.         with open(name + '.txt','w')as f:
  103.             f.write(name)
  104.         t.start()
  105.         print(zlist[i])
  106.         t.join(15)        
  107.     print('下一页')

  108.    


  109. def open_url(url):
  110.     time.sleep(1)
  111.     headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36',
  112.                
  113.                'referer':'https://www.busfan.cloud/',
  114.                'cookie':'自己添加'
  115.                ,"Connection": "close"
  116.                }
  117.     res = requests.get(url,headers = headers)
  118.     code = res.status_code
  119.     if code ==200:
  120.         print('成功打开主页:',res)
  121.         time.sleep(random.randint(1,3))
  122.         return res
  123.     else:
  124.         time.sleep(3)




  125. def main():
  126.     res = open_url(url)
  127.     find_data(res)

  128. if __name__ == '__main__':
  129.         
  130.     numx = 299
  131.     while numx >0:
  132.         url = 'https://www.busfan.cloud/forum/forum.php?mod=forumdisplay&fid=36&typeid=5&typeid=5&filter=typeid&page='+str(numx)
  133.         numx=numx-1
  134.         print('---------------开始--------------------','\n',numx,'@@##')
  135.         main()
复制代码

如图所示没有打印结果

如图所示没有打印结果

最佳答案

查看完整内容

多线程爬一个不可描述网站
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-10-25 17:30:43 | 显示全部楼层    本楼为最佳答案   
多线程爬一个不可描述网站
  1. import requests
  2. import bs4
  3. import time
  4. import os,sys
  5. import random
  6. from threading import Thread
  7. import re

  8. def down_jpg(url1,numm):
  9.     headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36',
  10.                
  11.                'referer':'newurl',
  12.                'cookie':'__cfduid=dccf7de8219a41296cc717949a14788851601881784; existmag=mag; 4fJN_2132_saltkey=aU1VYvxu; 4fJN_2132_lastvisit=1601882439; 4fJN_2132_visitedfid=36D2; PHPSESSID=6be8caov3lgjr4dhlsq9bm7rm7; 4fJN_2132_st_p=0%7C1602987046%7C5bc121f439bbf8cfe7e3512e0335a580; 4fJN_2132_viewid=tid_2117; 4fJN_2132_sid=IBh6Aq; 4fJN_2132_sendmail=1; 4fJN_2132_lastact=1602987586%09forum.php%09forumdisplay; 4fJN_2132_st_t=0%7C1602987586%7C88bfb33921f3da072fadcaf37c081bc4; 4fJN_2132_forum_lastvisit=D_2_1602946097D_36_1602987586'
  13.                ,"Connection": "close"
  14.                }
  15.     re = requests.get(url1,headers = headers)
  16.     img = re.content
  17.     print('downlond jpg',url1)
  18.     name = os.listdir()
  19.     for i in name:
  20.         if i !='http.txt' and i[-3:-1] =='tx':
  21.             name1 = name[0]+str(numm)+'1'
  22.     with open(name1+'.jpg','wb')as f:
  23.         f.write(img)

  24. def jpg_list(listy):
  25.     plist = []
  26.     num = len(listy)
  27.     for i in range(num):
  28.         t = Thread(target = down_jpg,args = (listy[i],i))
  29.         t.start()
  30.         plist.append(t)
  31.     for i in plist:
  32.         i.join()
  33.         print('图',i,'完成')
  34.     print('------over------')
  35.     time.sleep(10)
  36.    

  37. def find_new(res2,newurl):
  38.     num = 0
  39.     soup = bs4.BeautifulSoup(res2.text,'html.parser')
  40.     aaa = soup.find_all(onload='thumbImg(this)')
  41.     print('jpg...')
  42.     with open('http.txt','w',encoding='utf-8')as f:
  43.         f.write(soup.text)
  44.     listy = []
  45.     numy = 0
  46.     for i in aaa:
  47.         x = i.get('src')
  48.         listy.append(x)

  49.     jpg_list(listy)

  50.             

  51. def open_new(ilist):
  52.     headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36',
  53.                
  54.                'referer':url,
  55.                'cookie':'自己添加'
  56.                }
  57.     global newurl
  58.     newurl = 'https://www.busfan.cloud/forum/'+ilist
  59.     res2 = requests.get(newurl,headers = headers)
  60.     code = res2.status_code
  61.     if code ==200:
  62.         print('子页面连接成功',newurl)
  63.         time.sleep(random.randint(1,3))
  64.         soup = bs4.BeautifulSoup(res2.text,'html.parser')
  65.         print('txt...')
  66.         name0 = os.getcwd()
  67.         name = re.findall("[\u4e00-\u9fa5]+",name0)   
  68.         find_new(res2,newurl)
  69.     else:
  70.         print('打不开')


  71.         
  72. def find_data(res):
  73.     print('解析主页拿到子页面地址和名称')
  74.     zlist = []
  75.     pathlist = []
  76.     soup = bs4.BeautifulSoup(res.text,'html.parser')
  77.     aaa = soup.find_all(onclick = 'atarget(this)')
  78.     for new in aaa:
  79.         ilist = new.get('href')#子页面地址
  80.         name = new.text   #子页面名称
  81.         print('得到:',name)
  82.         path = 'M:\\3\\'+name
  83.         os.chdir('M:\\3')
  84.         lj = os.listdir()
  85.         for xi in lj:
  86.             if name == xi:
  87.                 print('删除重复文件夹',xi)
  88.                 os.chdir(path)
  89.                 file = os.listdir()
  90.                 for zi in file:
  91.                     os.remove(zi)
  92.                 os.chdir('M:\\3')
  93.                 os.rmdir(path)
  94.         
  95.         zlist.append(ilist)
  96.         pathlist.append(path)

  97.     num = len(zlist)
  98.     for i in range(num):
  99.         t = Thread(target = open_new,args = (zlist[i],))
  100.         os.mkdir(pathlist[i])
  101.         os.chdir(pathlist[i])
  102.         with open(name + '.txt','w')as f:
  103.             f.write(name)
  104.         t.start()
  105.         print(zlist[i])
  106.         t.join(15)        
  107.     print('下一页')

  108.    


  109. def open_url(url):
  110.     time.sleep(1)
  111.     headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36',
  112.                
  113.                'referer':'https://www.busfan.cloud/',
  114.                'cookie':'自己添加'
  115.                ,"Connection": "close"
  116.                }
  117.     res = requests.get(url,headers = headers)
  118.     code = res.status_code
  119.     if code ==200:
  120.         print('成功打开主页:',res)
  121.         time.sleep(random.randint(1,3))
  122.         return res
  123.     else:
  124.         time.sleep(3)




  125. def main():
  126.     res = open_url(url)
  127.     find_data(res)

  128. if __name__ == '__main__':
  129.         
  130.     numx = 299
  131.     while numx >0:
  132.         url = 'https://www.busfan.cloud/forum/forum.php?mod=forumdisplay&fid=36&typeid=5&typeid=5&filter=typeid&page='+str(numx)
  133.         numx=numx-1
  134.         print('---------------开始--------------------','\n',numx,'@@##')
  135.         main()
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-10-25 18:20:03 | 显示全部楼层
对于一个生产消费者模型的两个线程。
  1. def main():
  2.     pageQueue = Queue()   #给一个队列
  3.     for page in range(1,4): #爬去页数
  4.         pageQueue.put(page)  #往队列里面增加数据

  5.     #初始化采集线程
  6.     crawl_threads = []
  7.     crwal_name_list = ["crawl_1","crawl_2","crwal_3"]
  8.     for thread_id in crwal_name_list:
  9.         thread = Crawl_thread(thread_id,pageQueue)
  10.         thread.start()#启动线程
  11.         crawl_threads.append(thread)

  12.     #初始化解析线程
  13.     parser_threads = []
  14.     parser_name = ["parser_1","parser_2","parser_3"]
  15.     for thread_id in parser_name:
  16.         thread = Parser_thread(thread_id,data_queue)
  17.         thread.start()#启动线程
  18.         parser_threads.append(thread)

  19.     #等待队列情况
  20.     while not pageQueue.empty(): #判断是否为空 采集队列
  21.         pass

  22.     #等待所有线程结束
  23.     for t in crawl_threads:
  24.         t.join()

  25.     while not data_queue.empty():  #解析的队列
  26.         pass

  27.     #通知线程退出
  28.     global flag
  29.     flag =True
  30.     for t in parser_threads:
  31.         t.join()
  32.     print("退出主线程")


  33. data_queue = Queue() #创建一个队列
  34. flag = False
  35. if __name__ == "__main__":
  36.     main()
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-10-25 20:45:51 | 显示全部楼层
你看代码没用的。你首先得理解多线程的概念。 主线程—启动N个线程后,N个线程和主线程是同时在运行的,你如果想让N个线程执行完后再继续执行主线程,可以用一个循环函数(如while)分别获取N个函数的返回值(或者是用其他操作来判断是否执行完毕),如果每个线程都提供了返回值,则跳出循环
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-28 15:16

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表