多线程爬取二手房网页并将数据保存到mongodb的代码:

  1. import pymongo
  2. import threading
  3. import time
  4.  
  5. from lxml import etree
  6. import requests
  7. from queue import Queue
  8.  
  9. index_url='https://m.lianjia.com/gz/ershoufang/pg{}/'
  10. detail_url='https://m.lianjia.com{}'
  11.  
  12. # 设置爬取主页的页数
  13. INDEX_PAGE_NUM=
  14.  
  15. # 定义一个类
  16.  
  17. # 0定义主页url队列、主页html队列、详情页url队列、html队列、内容队列
  18. # 1获取首页url并解析详情页url
  19. # 2获取详情页的内容
  20. # 3保存内容
  21. # 4设置多线程调用方法
  22.  
  23. # 设置mongodb
  24. client = pymongo.MongoClient('localhost')
  25. # 设置数据库名
  26. db = client['ershoufang']
  27. # 指定集合名
  28. index = 'index_info'
  29. detail = 'detail_info'
  30.  
  31. class lianJia():
  32. def __init__(self):
  33. self.index_url_queue=Queue()
  34.  
  35. self.html_index_queue=Queue()
  36.  
  37. self.index_content_queue=Queue()
  38. self.detail_content_queue = Queue()
  39.  
  40. # 获取主页的url和html内容并解析出index页内容和详情页url
  41. def get_index(self):
  42. for i in range(INDEX_PAGE_NUM):
  43. # print(index_url.format(i+))
  44. url=index_url.format(i+)
  45. self.index_url_queue.put(url)
  46. # index=requests.get(index_url.format(i+)).content.decode()
  47. # self.html_index_queue.put(index)
  48. # 获取主页html
  49. def get_index_html(self):
  50. while True:
  51. url=self.index_url_queue.get()
  52. index = requests.get(url).content.decode()
  53. self.html_index_queue.put(index)
  54. self.index_url_queue.task_done()
  55. def parse_index(self):
  56. while True:
  57. # 获取队列里得内容
  58. html1=self.html_index_queue.get()
  59. xml=etree.HTML(html1)
  60. pingjie_list=xml.xpath('''//ul[@class='lists']/li[position()>1]''')
  61. # 将 pingjie_list拼接在xpath前,少写xpath语句
  62. index_content_list=[]
  63. for pj in pingjie_list:
  64. index_infor={}
  65. # #判空炒作,如果为空则显示none if len(index_infor['title']) > else None
  66. index_infor['title']=pj.xpath('''./div/div[@class='item_list']/div[1]/text()''')
  67.  
  68. index_infor['title']=index_infor['title'][] if len(index_infor['title']) > else None
  69. index_infor['detail_url'] = pj.xpath('''./a/@href''')[]
  70. index_infor['index_detail']=pj.xpath('''./div/div[2]/div[2]/text()''')
  71. index_infor['index_detail']=index_infor['index_detail'][] if len(index_infor['index_detail'])> else None
  72. index_infor['total_price']=pj.xpath('''./div/div[2]/div[position()>2]/span[1]/em/text()''')
  73. index_infor['total_price']= index_infor['total_price'][] if len( index_infor['total_price'])> else None
  74. index_infor['average_price']=pj.xpath('''./div/div[@class='item_list']/div[3]/span[2]/text()''')
  75. index_infor['average_price']=index_infor['average_price'][]if len(index_infor['average_price'])> else None
  76. index_content_list.append(index_infor)
  77. # 队列保存时不能在循环里 否之回保存很多个队列
  78. # self.index_content_queue.put(index_content_list)
  79. # 把content_list放进content_queue里面
  80.  
  81. self.index_content_queue.put(index_content_list)
  82. # print(index_content_list)
  83.  
  84. # 每从队列中获取一个数,队列则减少一个数,所以此代码必须写
  85. self.html_index_queue.task_done()
  86.  
  87. # 获取详情页内容
  88. def get_detail(self):
  89. pass
  90.  
  91. # 保存内容
  92. def save_content(self):
  93. while True:
  94. index_conten_list=self.index_content_queue.get()
  95.  
  96. for i in index_conten_list:
  97. # print(i['title'])
  98. if i['title']==None or i['total_price']==None or i['average_price']==None:
  99. print('该数据为空,不进行保存')
  100.  
  101. else:
  102. db['index_info'].insert(i)
  103. # db['detailDta'].insert(detail_datas)
  104. print('保存数据成功')
  105. self.index_content_queue.task_done()
  106.  
  107. # 主线程:分配各种子线程去执行class里得每一个函数
  108. # 使用队列的方式得设置多线程进行调用函数,才能让程序执行速度更快
  109. def run(self):
  110. # 设置线程列表
  111. thread_list=[]
  112. # start_time=time.time()
  113. # .url_list
  114. # threading.Thread不需要传参数,参数都是从队列里面取得
  115. # for i in range():
  116. t_index_u=threading.Thread(target=self.get_index)
  117. thread_list.append(t_index_u)
  118.  
  119. # .遍历,发送请求,获取响应
  120. for i in range():
  121. t_index_html=threading.Thread(target=self.get_index_html)
  122. thread_list.append(t_index_html)
  123.  
  124. # .提取数据
  125. for i in range():
  126. t_parse_index=threading.Thread(target=self.parse_index)
  127. thread_list.append(t_parse_index)
  128.  
  129. # .保存数据
  130. t_save=threading.Thread(target=self.save_content)
  131. thread_list.append(t_save)
  132. # 循环开启各子线程
  133. for t in thread_list:
  134. # 表示主线程结束,子线程(设置为true无限循环)也跟着结束(用主线程控制子线程)
  135. t.setDaemon(True)
  136. # 启动线程
  137. t.start()
  138. for q in [self.index_url_queue,self.html_index_queue,self.index_content_queue]:
  139. # 让主线程等待阻塞,等待队列的任务完成(即队列为空时 )之后再进行主线程
  140. q.join()
  141. # end_time=time.time()
  142. # print('总耗时%.2f秒'%(end_time-start_time))
  143.  
  144. if __name__=='__main__':
  145. sk = time.clock()
  146. func=lianJia()
  147. func.run()
  148. ek = time.clock()
  149. print('程序总耗时:',ek-sk)

多线程爬取糗事百科:

  1. # coding=utf-
  2. import requests
  3. from lxml import etree
  4. import threading
  5. from queue import Queue
  6.  
  7. # https://docs.python.org/3/library/queue.html#module-queue
  8. # 队列使用方法简介
  9. # q.qsize() 返回队列的大小
  10. # q.empty() 如果队列为空,返回True,反之False
  11. # q.full() 如果队列满了,返回True,反之False
  12. # q.full 与 maxsize 大小对应
  13. # q.get([block[, timeout]]) 获取队列,timeout等待时间
  14. # q.get_nowait() 相当q.get(False)
  15. # q.put(item) 写入队列,timeout等待时间
  16. # q.put_nowait(item) 相当q.put(item, False)
  17. # q.task_done() 在完成一项工作之后,q.task_done() 函数向任务已经完成的队列发送一个信号
  18. # q.join() 实际上意味着等到队列为空,再执行别的操作
  19.  
  20. class QiubaiSpdier:
  21. def __init__(self):
  22. self.url_temp = "https://www.qiushibaike.com/8hr/page/{}/"
  23. self.headers = {"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36"}
  24. self.url_queue = Queue()
  25. self.html_queue = Queue()
  26. self.content_queue = Queue()
  27. def get_url_list(self):
  28. # return [self.url_temp.format(i) for i in range(,)]
  29. for i in range(,):
  30. # 把13个索引页面的Url放进url_queue队列里
  31. self.url_queue.put(self.url_temp.format(i))
  32.  
  33. def parse_url(self):
  34. while True:
  35. # get方法和task_done搭配使用
  36. # 在put是队列+,get和task_done一起使用时队列才会-
  37. url = self.url_queue.get()
  38. print(url)
  39. response = requests.get(url,headers=self.headers)
  40. # 然后把索引页的响应页面放进html_queue队列里
  41. self.html_queue.put(response.content.decode())
  42. self.url_queue.task_done()
  43.  
  44. def get_content_list(self): #提取数据
  45. while True:
  46. # 先从索引页响应页面html_queue队列里面取出索引页面
  47. html_str = self.html_queue.get()
  48.  
  49. html = etree.HTML(html_str)
  50. div_list = html.xpath("//div[@id='content-left']/div") #分组
  51. content_list = []
  52. for div in div_list:
  53. item= {}
  54. item["content"] = div.xpath(".//div[@class='content']/span/text()")
  55. item["content"] = [i.replace("\n","") for i in item["content"]]
  56. item["author_gender"] = div.xpath(".//div[contains(@class,'articleGender')]/@class")
  57. item["author_gender"] = item["author_gender"][].split(" ")[-].replace("Icon","") if len(item["author_gender"])> else None
  58. item["auhtor_age"] = div.xpath(".//div[contains(@class,'articleGender')]/text()")
  59. item["auhtor_age"] = item["auhtor_age"][] if len(item["auhtor_age"])> else None
  60. item["content_img"] = div.xpath(".//div[@class='thumb']/a/img/@src")
  61. item["content_img"] = "https:"+item["content_img"][] if len(item["content_img"])> else None
  62. item["author_img"] = div.xpath(".//div[@class='author clearfix']//img/@src")
  63. item["author_img"] = "https:"+item["author_img"][] if len(item["author_img"])> else None
  64. item["stats_vote"] = div.xpath(".//span[@class='stats-vote']/i/text()")
  65. item["stats_vote"] = item["stats_vote"][] if len(item["stats_vote"])> else None
  66. content_list.append(item)
  67. # 把content_list放进content_queue里面
  68. self.content_queue.put(content_list)
  69. self.html_queue.task_done()
  70.  
  71. def save_content_list(self): #保存
  72. while True:
  73. content_list = self.content_queue.get()
  74. for i in content_list:
  75. print(i)
  76. pass
  77. self.content_queue.task_done()
  78.  
  79. def run(self): #实现主要逻辑
  80. thread_list = []
  81. #.url_list
  82. # threading.Thread不需要传参数,参数都是从队列里面取得
  83. t_url = threading.Thread(target=self.get_url_list)
  84. thread_list.append(t_url)
  85. #.遍历,发送请求,获取响应
  86. for i in range(): # 添加20个线程
  87. t_parse = threading.Thread(target=self.parse_url)
  88. thread_list.append(t_parse)
  89. #.提取数据
  90. for i in range(): # 添加2个线程
  91. t_html = threading.Thread(target=self.get_content_list)
  92. thread_list.append(t_html)
  93. #.保存
  94. t_save = threading.Thread(target=self.save_content_list)
  95. thread_list.append(t_save)
  96. for t in thread_list:
  97. t.setDaemon(True) #把子线程设置为守护线程,该线程不重要,主线程结束,子线程结束(子线程是while true不会自己结束)
  98. t.start()
  99.  
  100. for q in [self.url_queue,self.html_queue,self.content_queue]:
  101. q.join() #让主线程等待阻塞,等待队列的任务完成(即队列为空时 )之后再进行主线程
  102.  
  103. print("主线程结束")
  104.  
  105. if __name__ == '__main__':
  106. qiubai = QiubaiSpdier()
  107. qiubai.run()
  108.  
  109. # 所没有tast_done方法,程序最终会卡着不动,无法终止
  110.  
  111. # 线程的设计注意:耗时的操作要分配一些线程

实现多线程爬取数据并保存到mongodb的更多相关文章

  1. scrapy爬取海量数据并保存在MongoDB和MySQL数据库中

    前言 一般我们都会将数据爬取下来保存在临时文件或者控制台直接输出,但对于超大规模数据的快速读写,高并发场景的访问,用数据库管理无疑是不二之选.首先简单描述一下MySQL和MongoDB的区别:MySQ ...

  2. sumafan:python爬虫多线程爬取数据小练习(附答案)

    抓取 https://www.cnbeta.com/ 首页中新闻内容页网址, 抓取内容例子: https://hot.cnbeta.com/articles/game/825125 将抓取下来的内容页 ...

  3. 吴裕雄--天生自然python数据清洗与数据可视化:MYSQL、MongoDB数据库连接与查询、爬取天猫连衣裙数据保存到MongoDB

    本博文使用的数据库是MySQL和MongoDB数据库.安装MySQL可以参照我的这篇博文:https://www.cnblogs.com/tszr/p/12112777.html 其中操作Mysql使 ...

  4. 吴裕雄--天生自然PYTHON爬虫:安装配置MongoDBy和爬取天气数据并清洗保存到MongoDB中

    1.下载MongoDB 官网下载:https://www.mongodb.com/download-center#community 上面这张图选择第二个按钮 上面这张图直接Next 把bin路径添加 ...

  5. python多线程爬取斗图啦数据

    python多线程爬取斗图啦网的表情数据 使用到的技术点 requests请求库 re 正则表达式 pyquery解析库,python实现的jquery threading 线程 queue 队列 ' ...

  6. Python爬虫入门教程 11-100 行行网电子书多线程爬取

    行行网电子书多线程爬取-写在前面 最近想找几本电子书看看,就翻啊翻,然后呢,找到了一个 叫做 周读的网站 ,网站特别好,简单清爽,书籍很多,而且打开都是百度网盘可以直接下载,更新速度也还可以,于是乎, ...

  7. 借助Chrome和插件爬取数据

    工具 Chrome浏览器 TamperMonkey ReRes Chrome浏览器 chrome浏览器是目前最受欢迎的浏览器,没有之一,它兼容大部分的w3c标准和ecma标准,对于前端工程师在开发过程 ...

  8. 使用selenium 多线程爬取爱奇艺电影信息

    使用selenium 多线程爬取爱奇艺电影信息 转载请注明出处. 爬取目标:每个电影的评分.名称.时长.主演.和类型 爬取思路: 源文件:(有注释) from selenium import webd ...

  9. Python爬虫入门教程 14-100 All IT eBooks多线程爬取

    All IT eBooks多线程爬取-写在前面 对一个爬虫爱好者来说,或多或少都有这么一点点的收集癖 ~ 发现好的图片,发现好的书籍,发现各种能存放在电脑上的东西,都喜欢把它批量的爬取下来. 然后放着 ...

随机推荐

  1. 【CH6801】棋盘覆盖

    题目大意:给定一个 N*N 的棋盘,棋盘上有些位置不能防止任何东西,现用 1*2 的骨牌填充棋盘,问最多能铺多少块骨牌. 题解:由于骨牌只能覆盖相邻的两个格子,那么按照对角线进行划分的格子可以保证一定 ...

  2. (转)visual stdio 书签功能介绍

    http://www.mycode.net.cn/tools/1615.html 使用 Visual Studio 开发过程中,你很容易遇到一种情况就是多个文件来回的切换,在每一块实现不同的业务,打开 ...

  3. 判断JDK安装成功的方法

    JDK安装成功之后,主要是要写入环境变量

  4. Nginx概述及安装配置

    1.概述 Nginx是一款开源的,高性能的Http和反向代理服务器,同时也是一个IMAP.POP3.SMTP代理服务器:Nginx可以作为一个HTTP服务器进行网站的发布处理,也可以作为反向代理进行负 ...

  5. python实现发送邮件

    一 使用SMTP模块发送邮件 import smtplib from email.mime.text import MIMEText from email.header import Header m ...

  6. Ubuntu下添加Samba用户名与密码

    参考: ubuntu下的Samba配置:使每个用户可以用自己的用户名和密码登录自己的home目录 增加samba用户提示Failed to add entry for user Ubuntu可以直接在 ...

  7. HDU - 5952 Counting Cliques(DFS)

    A clique is a complete graph, in which there is an edge between every pair of the vertices. Given a ...

  8. mysql 5.7安装准备

    在5.5之后的mysql安装中,需要使用cmake来指定安装参数,下面列出关于cmake的几个常用参数: CMAKE_INSTALL_PREFIX:指定MySQL程序的安装目录,默认/usr/loca ...

  9. Zabbix Web API Get方法整合

    #!/usr/bin/python3 import requests,json,re,time,datetime     url = 'http://xxx.com/api_jsonrpc.php' ...

  10. java io系列19之 CharArrayWriter(字符数组输出流)

    本章,我们学习CharArrayWriter.学习时,我们先对CharArrayWriter有个大致了解,然后深入了解一下它的源码,最后通过示例来掌握它的用法. 转载请注明出处:http://www. ...