1、链接mongodbhtml
一、 设置数据库 client=pymongo.MongoClient(‘localhost’)python
二、 db=client[‘lagou’]设置链接的数据库名称mongodb
POSITION_NAME=’’ 、PAGE_SUM 、PAGE_SIZE 等为你设置的变量名称。
三、DATA_NAME=’dataposition’ # # 指定数据库的名字
四、设置保存在mongo数据库中的数据:
def save_to_mongo(data):
if db[DATA_NAME].update({'positionId': data['positionId']}, {'$set': data}, True):
print('Saved to Mongo', data['positionId'])
else:
print('Saved to Mongo Failed', data['positionId'])
这是以positionId为惟一标识,若是数据库里面已经存在有positionId,说明数据已经爬过了,再也不更新。
2、多进程设置和使用:
一、导入多进程:from multiprocessing import Pool
导入时间 import time
二、start_time = time.time()
pool = Pool() # pool()参数:进程个数:默认的是电脑cpu的核的个数,若是要指定进程个数,这个进程个数要小于等于cpu的核数
# 第一个参数是一个函数体,不须要加括号,也不需指定参数。。
# 第二个参数是一个列表,列表中的每一个参数都会传给那个函数体
pool.map(to_mongo_pool,[i for i in range(PAGE_SUM)])
# close它只是把进程池关闭
pool.close()
# join起到一个阻塞的做用,主进程要等待子进程运行完,才能接着往下运行
pool.join()
end_time = time.time()
print("总耗费时间%.2f秒" % (end_time - start_time))
to_mongo_pool:这个函数要设计好,就一个参数就够了,而后把它的参数放在列表里面,经过map高阶函数一次传给to_mongo_pool数据库
多线程的使用:多线程
多线程要配合队列使用:app
# coding=utf-8函数
import requests
from lxml import etree
import threading 导入线程
from queue import Queue 导入队列
# https://docs.python.org/3/library/queue.html#module-queu
# 队列使用方法简介
# 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 Lianjia:
def __init__(self):
self.url_temp = url = "https://gz.lianjia.com/ershoufang/pg{}/"
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(1,14)]
for i in range(1, 14):
# 把13个索引页面的Url放进url_queue队列里
self.url_queue.put(self.url_temp.format(i))
定义运行函数url
def run(self): # 实现主要逻辑 thread_list = [] # 1.url_list # threading.Thread不须要传参数,参数都是从队列里面取得 t_url = threading.Thread(target=self.get_url_list) thread_list.append(t_url) # 2.遍历,发送请求,获取响应 for i in range(20): # 添加20个线程 t_parse = threading.Thread(target=self.parse_url) thread_list.append(t_parse) # 3.提取数据 for i in range(2): # 添加2个线程 t_html = threading.Thread(target=self.get_content_list) thread_list.append(t_html) # 4.保存 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("主线程结束")