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

import pymongo
import threading
import time from lxml import etree
import requests
from queue import Queue index_url='https://m.lianjia.com/gz/ershoufang/pg{}/'
detail_url='https://m.lianjia.com{}' # 设置爬取主页的页数
INDEX_PAGE_NUM= # 定义一个类 # 0定义主页url队列、主页html队列、详情页url队列、html队列、内容队列
# 1获取首页url并解析详情页url
# 2获取详情页的内容
# 3保存内容
# 4设置多线程调用方法 # 设置mongodb
client = pymongo.MongoClient('localhost')
# 设置数据库名
db = client['ershoufang']
# 指定集合名
index = 'index_info'
detail = 'detail_info' class lianJia():
def __init__(self):
self.index_url_queue=Queue() self.html_index_queue=Queue() self.index_content_queue=Queue()
self.detail_content_queue = Queue() # 获取主页的url和html内容并解析出index页内容和详情页url
def get_index(self):
for i in range(INDEX_PAGE_NUM):
# print(index_url.format(i+))
url=index_url.format(i+)
self.index_url_queue.put(url)
# index=requests.get(index_url.format(i+)).content.decode()
# self.html_index_queue.put(index)
# 获取主页html
def get_index_html(self):
while True:
url=self.index_url_queue.get()
index = requests.get(url).content.decode()
self.html_index_queue.put(index)
self.index_url_queue.task_done()
def parse_index(self):
while True:
# 获取队列里得内容
html1=self.html_index_queue.get()
xml=etree.HTML(html1)
pingjie_list=xml.xpath('''//ul[@class='lists']/li[position()>1]''')
# 将 pingjie_list拼接在xpath前,少写xpath语句
index_content_list=[]
for pj in pingjie_list:
index_infor={}
# #判空炒作,如果为空则显示none if len(index_infor['title']) > else None
index_infor['title']=pj.xpath('''./div/div[@class='item_list']/div[1]/text()''') index_infor['title']=index_infor['title'][] if len(index_infor['title']) > else None
index_infor['detail_url'] = pj.xpath('''./a/@href''')[]
index_infor['index_detail']=pj.xpath('''./div/div[2]/div[2]/text()''')
index_infor['index_detail']=index_infor['index_detail'][] if len(index_infor['index_detail'])> else None
index_infor['total_price']=pj.xpath('''./div/div[2]/div[position()>2]/span[1]/em/text()''')
index_infor['total_price']= index_infor['total_price'][] if len( index_infor['total_price'])> else None
index_infor['average_price']=pj.xpath('''./div/div[@class='item_list']/div[3]/span[2]/text()''')
index_infor['average_price']=index_infor['average_price'][]if len(index_infor['average_price'])> else None
index_content_list.append(index_infor)
# 队列保存时不能在循环里 否之回保存很多个队列
# self.index_content_queue.put(index_content_list)
# 把content_list放进content_queue里面 self.index_content_queue.put(index_content_list)
# print(index_content_list) # 每从队列中获取一个数,队列则减少一个数,所以此代码必须写
self.html_index_queue.task_done() # 获取详情页内容
def get_detail(self):
pass # 保存内容
def save_content(self):
while True:
index_conten_list=self.index_content_queue.get() for i in index_conten_list:
# print(i['title'])
if i['title']==None or i['total_price']==None or i['average_price']==None:
print('该数据为空,不进行保存') else:
db['index_info'].insert(i)
# db['detailDta'].insert(detail_datas)
print('保存数据成功')
self.index_content_queue.task_done() # 主线程:分配各种子线程去执行class里得每一个函数
# 使用队列的方式得设置多线程进行调用函数,才能让程序执行速度更快
def run(self):
# 设置线程列表
thread_list=[]
# start_time=time.time()
# .url_list
# threading.Thread不需要传参数,参数都是从队列里面取得
# for i in range():
t_index_u=threading.Thread(target=self.get_index)
thread_list.append(t_index_u) # .遍历,发送请求,获取响应
for i in range():
t_index_html=threading.Thread(target=self.get_index_html)
thread_list.append(t_index_html) # .提取数据
for i in range():
t_parse_index=threading.Thread(target=self.parse_index)
thread_list.append(t_parse_index) # .保存数据
t_save=threading.Thread(target=self.save_content)
thread_list.append(t_save)
# 循环开启各子线程
for t in thread_list:
# 表示主线程结束,子线程(设置为true无限循环)也跟着结束(用主线程控制子线程)
t.setDaemon(True)
# 启动线程
t.start()
for q in [self.index_url_queue,self.html_index_queue,self.index_content_queue]:
# 让主线程等待阻塞,等待队列的任务完成(即队列为空时 )之后再进行主线程
q.join()
# end_time=time.time()
# print('总耗时%.2f秒'%(end_time-start_time)) if __name__=='__main__':
sk = time.clock()
func=lianJia()
func.run()
ek = time.clock()
print('程序总耗时:',ek-sk)

多线程爬取糗事百科:

# coding=utf-
import requests
from lxml import etree
import threading
from queue import Queue # https://docs.python.org/3/library/queue.html#module-queue
# 队列使用方法简介
# q.qsize() 返回队列的大小
# q.empty() 如果队列为空,返回True,反之False
# q.full() 如果队列满了,返回True,反之False
# q.full 与 maxsize 大小对应
# q.get([block[, timeout]]) 获取队列,timeout等待时间
# q.get_nowait() 相当q.get(False)
# q.put(item) 写入队列,timeout等待时间
# q.put_nowait(item) 相当q.put(item, False)
# q.task_done() 在完成一项工作之后,q.task_done() 函数向任务已经完成的队列发送一个信号
# q.join() 实际上意味着等到队列为空,再执行别的操作 class QiubaiSpdier:
def __init__(self):
self.url_temp = "https://www.qiushibaike.com/8hr/page/{}/"
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"}
self.url_queue = Queue()
self.html_queue = Queue()
self.content_queue = Queue()
def get_url_list(self):
# return [self.url_temp.format(i) for i in range(,)]
for i in range(,):
# 把13个索引页面的Url放进url_queue队列里
self.url_queue.put(self.url_temp.format(i)) def parse_url(self):
while True:
# get方法和task_done搭配使用
# 在put是队列+,get和task_done一起使用时队列才会-
url = self.url_queue.get()
print(url)
response = requests.get(url,headers=self.headers)
# 然后把索引页的响应页面放进html_queue队列里
self.html_queue.put(response.content.decode())
self.url_queue.task_done() def get_content_list(self): #提取数据
while True:
# 先从索引页响应页面html_queue队列里面取出索引页面
html_str = self.html_queue.get() html = etree.HTML(html_str)
div_list = html.xpath("//div[@id='content-left']/div") #分组
content_list = []
for div in div_list:
item= {}
item["content"] = div.xpath(".//div[@class='content']/span/text()")
item["content"] = [i.replace("\n","") for i in item["content"]]
item["author_gender"] = div.xpath(".//div[contains(@class,'articleGender')]/@class")
item["author_gender"] = item["author_gender"][].split(" ")[-].replace("Icon","") if len(item["author_gender"])> else None
item["auhtor_age"] = div.xpath(".//div[contains(@class,'articleGender')]/text()")
item["auhtor_age"] = item["auhtor_age"][] if len(item["auhtor_age"])> else None
item["content_img"] = div.xpath(".//div[@class='thumb']/a/img/@src")
item["content_img"] = "https:"+item["content_img"][] if len(item["content_img"])> else None
item["author_img"] = div.xpath(".//div[@class='author clearfix']//img/@src")
item["author_img"] = "https:"+item["author_img"][] if len(item["author_img"])> else None
item["stats_vote"] = div.xpath(".//span[@class='stats-vote']/i/text()")
item["stats_vote"] = item["stats_vote"][] if len(item["stats_vote"])> else None
content_list.append(item)
# 把content_list放进content_queue里面
self.content_queue.put(content_list)
self.html_queue.task_done() def save_content_list(self): #保存
while True:
content_list = self.content_queue.get()
for i in content_list:
print(i)
pass
self.content_queue.task_done() def run(self): #实现主要逻辑
thread_list = []
#.url_list
# threading.Thread不需要传参数,参数都是从队列里面取得
t_url = threading.Thread(target=self.get_url_list)
thread_list.append(t_url)
#.遍历,发送请求,获取响应
for i in range(): # 添加20个线程
t_parse = threading.Thread(target=self.parse_url)
thread_list.append(t_parse)
#.提取数据
for i in range(): # 添加2个线程
t_html = threading.Thread(target=self.get_content_list)
thread_list.append(t_html)
#.保存
t_save = threading.Thread(target=self.save_content_list)
thread_list.append(t_save)
for t in thread_list:
t.setDaemon(True) #把子线程设置为守护线程,该线程不重要,主线程结束,子线程结束(子线程是while true不会自己结束)
t.start() for q in [self.url_queue,self.html_queue,self.content_queue]:
q.join() #让主线程等待阻塞,等待队列的任务完成(即队列为空时 )之后再进行主线程 print("主线程结束") if __name__ == '__main__':
qiubai = QiubaiSpdier()
qiubai.run() # 所没有tast_done方法,程序最终会卡着不动,无法终止 # 线程的设计注意:耗时的操作要分配一些线程

实现多线程爬取数据并保存到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. key-event

    效果如下 代码如下: 首先看目录 //index.html <!DOCTYPE html> <html lang="zh-CN"> <head> ...

  2. 斯坦福大学公开课机器学习: advice for applying machine learning | deciding what to try next(revisited)(针对高偏差、高方差问题的解决方法以及隐藏层数的选择)

    针对高偏差.高方差问题的解决方法: 1.解决高方差问题的方案:增大训练样本量.缩小特征量.增大lambda值 2.解决高偏差问题的方案:增大特征量.增加多项式特征(比如x1*x2,x1的平方等等).减 ...

  3. Day20--Python--约束和异常处理

    1. 异常处理(处理异常,抛出异常,自定义异常) 异常: 程序运行过程中产生的错误 1. 产生异常. raise 异常类(), 抛出异常 2. 处理异常: try: xxxxxxxx # 尝试执行的代 ...

  4. ElasticSearch6.5.0 【字段类型】

    字符串类型 text 适合全文索引,有分析的过程 keyword 适合结构化的数据,比如地址.电话号码... 数字 long [带符号64位整数]范围:-263 ~ 263-1 integer     ...

  5. SpringBoot+Shiro+Redis共享Session入门小栗子

    在单机版的Springboot+Shiro的基础上,这次实现共享Session. 这里没有自己写RedisManager.SessionDAO.用的 crazycake 写的开源插件 pom.xml ...

  6. 将Excel导出为SQL语句

    需求说明:公司做项目前进行需求分析,确定表结构后需要建表,如果照着表格去敲,那就太麻烦了,所以想到了自动生成SQL语句. 思路大概就是:解析Excel,拼接SQL语句,输出SQL文件. 第三方jar包 ...

  7. selenium自动化测试原理和设计的分享

    昨天参加了公司的一个自动化测试的分享,有一些收获,记录一下. 1.主流的web端的UI自动化测试工具 基于浏览器API: selenium2.0,Watir(IE Driver) 基于JS 进行驱动: ...

  8. VMware for mac inside error solutions

    Terminal 下执行 sudo xattr -r -d com.apple.quarantine /Applications/VMware\ Fusion.app 之后就能正常打开镜像安装虚拟机了 ...

  9. 表连接join on

    表A记录如下:  aID aNum  1 a20050111  2 a20050112  3 a20050113  4 a20050114  5 a20050115  表B记录如下:  bID bNa ...

  10. Tornado基于MiddleWare做中间件

    详细代码如下: 在app.py里添加 # -*- coding:utf-8 -*- from tornado.ioloop import IOLoop from tornado.web import ...