豆弁グループの賃貸情報(mongo+node+vue)
11980 ワード
基本的な考え方
1.nodeの
2.豆弁はbanが爬虫類ipを落とすので、爬虫類の過程で
3.フロントエンドインタフェースはvueでip選択を提供し、フィルタ結果をページ別に表示し、リモートに配置されず、ローカルで走るとエージェントに関連し、主に
コード実装
ディレクトリ構造
Nodeエンド
db.js
インタフェース
プロジェクトの開始
1.コマンドラインで起動
2.コマンドラインに
3.コマンドラインに
プロジェクトアドレス
1.nodeの
superagent
によってhttp要求をシミュレートし、豆弁グループの情報を読み取り、cheerio
プラグインによって解析フォーマットを行い、body
の情報をmongodb
に格納する2.豆弁はbanが爬虫類ipを落とすので、爬虫類の過程で
ip
を使って使用したことのないipを選んで代理で爬虫類ipを取り、mapLimit
の同時使用を避ける3.フロントエンドインタフェースはvueでip選択を提供し、フィルタ結果をページ別に表示し、リモートに配置されず、ローカルで走るとエージェントに関連し、主に
vue.config.js
にあり、その後、mongodb
にすでに存在するデータを読み出してフロントエンドに表示する.コード実装
ディレクトリ構造
...
├── app.js
├── babel.config.js
...
...
├── server //
│ ├── db.js //
│ └── urls.js // url,
├── server.js //
...
├── src // vue
│ ├── App.vue
│ ├── api
│ ├── assets
│ ├── components
│ └── main.js
├── updatePoxy.js
├── vue.config.js
Nodeエンド
// server.js
//
//
//
const express = require('express');
const app = express();
let server = app.listen(2333, "127.0.0.1", function () {
let host = server.address().address;
let port = server.address().port;
console.log('Your App is running at' + host + ':' + port, );
})
//
//
//
const superagent = require('superagent');
const eventproxy = require('eventproxy');
const ipProxy = require('ip-proxy-pool');
const cheerio = require('cheerio');
const async = require('async');
require('superagent-proxy')(superagent);
// ,
const groups = require('./server/urls') // url,
let page = 1 //
let start = 24 //
// ulr
let ep = new eventproxy() // eventproxy
global.db = require('./server/db')
let allLength = 0
groups.map((gp) => {
gp.pageUrls = [] //
allLength = allLength + 1
for (let i = 0; i < page; i++) {
allLength = allLength + i
gp.pageUrls.push({
url: gp.url + i * start // https://www.douban.com/group/liwanzufang/discussion?start=0
});
}
})
//
const getPageInfo = (ip, pageItem, callback) => {
//
console.log('ip', ip)
let delay = parseInt((Math.random() * 30000000) % 1000, 10)
let resultBack = {label: pageItem.key, list: []}
pageItem.pageUrls.forEach(pageUrl => {
superagent.get(pageUrl.url).proxy(ip)
//
.set('User-Agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36')
// , kill ,
.set('Cookie', '')
.end((err, pres) => {
if (err || !pres) {
ep.emit('preparePage', [])
return
}
console.log('pres.text', pres.text)
let $ = cheerio.load(pres.text) // cheerio , jQuery
let itemList = $('.olt tbody').children().slice(1, 26) // table ,
//
for (let i = 0; i < itemList.length; i++) {
let item = itemList.eq(i).children()
let title = item.eq(0).children('a').text() || '' //
let url = item.eq(0).children('a').attr('href') || '' //
// let author = item.eq(1).children('a').attr('href').replace('https://www.douban.com/people', '').replace(/\//g, '') || '' // id
let author = item.eq(1).children('a').text() || '' // id , 。 , ,
let markSum = item.eq(2).text() //
let lastModify = item.eq(3).text() //
let data = {
title,
url,
author,
markSum,
lastModify,
label: pageItem.key
}
resultBack.list.push(data)
}
// ep.emit(' ', )
console.log('resultBack', resultBack)
ep.emit('preparePage', resultBack) // , preparePage ,
setTimeout(() => {
callback(null, pageItem.url);
}, delay);
})
})
}
function getData(ip, res) {
//
async.mapLimit(groups, 1, function (item, callback) {
getPageInfo(ip, item, callback);
}, function (err) {
if (err) {
console.log(err)
}
console.log(' ')
});
}
ep.after('preparePage', allLength, function (data, res) {
// , '|' 。 ,
let filterWords = / | | | /
//
let inserTodbList = []
data.forEach(item => {
// if ,
item.list = item.list.filter(() => {
if (item.markSum > 100) {
console.log(' , ')
return false
}
if (filterWords.test(item.title)) {
console.log(' ')
console.log('item', item)
return false
}
return true
})
inserTodbList.push(...item.list)
})
global.db.__insertMany('douban', inserTodbList, function () {
ep.emit('spiderEnd', {})
})
});
//
//
//
app.get('/api/getDataFromDouBan', (req, res) => {
let {ip} = req.query
getData(ip, res)
ep.after('spiderEnd', 1, function() {
res.send({
data: ' '
})
})
})
// ip
app.get('/api/getIps', (req, res) => {
async function getIps(callback) {
let ips = ipProxy.ips
ips((err,response) => {
callback(response)
})
}
getIps(function (ipList) {
res.send({
msg: ' ',
list: ipList
})
})
})
// ip
app.get('/api/updateIps', (req, res) => {
ipProxy.run(() => {
console.log(' ')
})
})
app.get('/api/doubanList', (req, res) => {
let {label, page = 1, pageSize = 10} = req.query
let param = []
label && label.map((item) => {
param.push({label: item})
})
let queryJson = {
// $where: "label"
}
if (param.length) queryJson['$or'] = param
global.db.__find('douban', {queryJson, page, pageSize}, function (data) {
res.send({
msg: ' ',
...data
})
})
})
db.js
// db.js
/**
*
*
*/
var MongodbClient = require('mongodb').MongoClient
var assert = require('assert')
var url = "mongodb://localhost:27017";
/**
*
*/
function __connectDB(callback) {
MongodbClient.connect(url, function (err, client) {
let db = client.db('zufangzi')
callback(err, db, client)
})
}
/**
*
* @param {*} collectionName
* @param {*} Datajson json
* @param {*} callback
*/
function __insertOne(collectionName, Datajson, callback) {
__connectDB(function (err, db, client) {
var collection = db.collection(collectionName);
collection.insertOne(Datajson, function (err, result) {
callback(err, result); //
client.close();
})
})
}
/**
*
* @param {*} collectionName
* @param {*} Datajson json
* @param {*} callback
*/
function __insertMany(collectionName, Datajson, callback) {
__connectDB(function (err, db, client) {
var collection = db.collection(collectionName);
collection.insertMany(Datajson, function (err, result) {
callback(err, result); //
client.close();
})
})
}
/**
*
* @param {*} collectionName
* @param {*} Datajson
* @param {*} callback
*/
function __find(collectionName, {queryJson, page, pageSize}, callback) {
var result = [];
if (arguments.length != 3) {
callback("find ", null)
return
}
__connectDB(async function (err, db, client) {
var cursor = db.collection(collectionName).find(queryJson).skip((page - 1) * pageSize).limit(10);
let total = await cursor.count()
if (!err) {
await cursor.forEach(function (doc) {
// ,
// console.log('doc', doc)
if (doc != null) {
result.push(doc)
}
})
callback({list: result, total})
}
client.close();
})
}
/**
*
* ( )
* @param {*} collectionName
* @param {*} json json
* @param {*} callback
*/
function __DeleteMany(collectionName, json, callback) {
__connectDB(function (err, db, client) {
assert.equal(err, null)
//
db.collection(collectionName).deleteMany(
json,
function (err, results) {
assert.equal(err, null)
callback(err, results);
client.close(); //
}
);
});
}
/**
*
* @param {*} collectionName
* @param {*} json1
* @param {*} json2
* @param {*} callback
*/
function __updateMany(collectionName, json1, json2, callback) {
__connectDB(function (err, db, client) {
assert.equal(err, null)
db.collection(collectionName).updateMany(
json1,
json2,
function (err, results) {
assert.equal(err, null)
callback(err, results)
client.close()
}
)
})
}
/**
*
* @param {*} collectionName
* @param {*} json
* @param {*} callback
*/
function __getCount(collectionName, json, callback) {
__connectDB(function (err, db, client) {
db.collection(collectionName).count(json).then(function (count) {
callback(count)
client.close();
})
})
}
/**
*
* @param {*} collectionName
* @param {*} JsonObj
* @param {*} C 【 】 , 、
* @param {*} C callback
*/
function __findByPage(collectionName, JsonObj, C, D) {
var result = []; //
if (arguments.length == 3) {
// C callback, D 。
var callback = C;
var skipnumber = 0;
//
var limit = 0;
} else if (arguments.length == 4) {
var callback = D;
var args = C;
//
var skipnumber = args.pageamount * args.page || 0;
//
var limit = args.pageamount || 0;
//
var sort = args.sort || {};
} else {
throw new Error("find , 3 , 4 。");
return;
}
// ,
__connectDB(function (err, db, client) {
var cursor = db.collection(collectionName).find(JsonObj).skip(skipnumber).limit(limit).sort(sort);
cursor.each(function (err, doc) {
if (err) {
callback(err, null);
client.close(); //
return;
}
if (doc != null) {
result.push(doc); //
} else {
// ,
callback(null, result);
client.close(); //
}
});
});
}
module.exports = {
__connectDB,
__insertOne,
__insertMany,
__find,
__DeleteMany,
__updateMany,
__getCount,
__findByPage
}
インタフェース
const axios = require('axios');
export const getHousData = async (arg = {}) => {
//
let respones = await axios.get('/api/doubanList', {
params: arg
})
return respones.data
}
export const spiderData = async (arg = {}) => {
//
let respones = await axios.get('/api/getDataFromDouBan/', {
params: arg
})
return respones.data
}
export const updateIps = async (arg = {}) => {
// ip
let respones = await axios.get('/api/updateIps/', {
params: arg
})
return respones.data
}
export const getIps = async (arg = {}) => {
// ip
let respones = await axios.get('/api/getIps/', {
params: arg
})
return respones.data
}
プロジェクトの開始
1.コマンドラインで起動
mongodb
入力:mongod
、インストールされていないものは自分でインストールする必要がある2.コマンドラインに
yarn dev
を入力してローカルフロントエンド項目を起動する3.コマンドラインに
nodemon server.js
を入力してバックエンド項目を起動するプロジェクトアドレス