多线程爬取二手房网页并将数据保存到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. echarts 调整图表大小的方法

    第一次使用Echarts,大小用的不是那么随心应手,通过文档和百度出的结果,发现其实很简单: 内部图表大小是与div容器大小相关的,如果想调整图表大小,调整div就可以了 如果是想调整图表与div间上 ...

  2. 利用/dev/urandom文件创建随机数

    1:/dev/urandom和/dev/random是什么 这两个文件记录Linux下的熵池,所谓熵池就是当前系统下的环境噪音,描述了一个系统的混乱程度,环境噪音由这几个方面组成,如内存的使用,文件的 ...

  3. P3358 最长k可重区间集问题

    题目链接 \(Click\) \(Here\) 这题的写法非常巧妙. 每个位置的点向它的下一个位置连一个容量为\(INF\)的边,从区间的左端点往右端点拉一条容量为\(1\),费用为区间长度的边,从起 ...

  4. cmd解压压缩包

    需要安装有winrar start winrar x C:\Users\systme\Desktop\xxx.rar c:\123

  5. qml: 另类图像轮播;

    一般来说,图像轮播都是采用ListView等model进行设计, 比较方便.  这里展示我自己设计的图像轮播 方案, 仅采用两个QImage实现: 下面展示代码以及简述:(注:  以下代码为本人原创, ...

  6. centos7下安装pip以及mysql等软件

    1.安装pip 安装失败了的提示: No package pip available.Error: Nothing to do 解决方法: 需要先安装扩展源EPEL. EPEL(http://fedo ...

  7. 【JAVA】使用IntelliJ IDEA创建Java控制台工程

    1.File->New->Project 2.选择Java,下一步 3.模板有两个:Command Line App和Java Hello World,没有太大区别 4.命名: 5.结果:

  8. python 包和模块间的引入

    ##############################总结####################### 主要内容: 1. 模块 2. import 3. from xxx import xxx ...

  9. ruby批量插入数据,bulk_insert-----Gem包使用

    文档 https://github.com/jamis/bulk_insert class Book < ActiveRecord::Base end book_attrs = ... # so ...

  10. 【整理】Linux 下 自己使用的 debug宏 printf

    #ifdef __DEBUG_PRINTF__ /* * * Some Debug printf kit for devlopment * * Date : 2019.03.04 * * Editor ...