成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

手把手教你如何用Crawlab構建技術文章聚合平臺(二)

zhunjiee / 1638人閱讀

摘要:上一篇文章手把手教你如何用構建技術文章聚合平臺一介紹了如何使用搭建的運行環(huán)境,并且將與集成,對掘金進行技術文章的抓取,最后可以查看抓取結果。本篇文章將繼續(xù)講解如何利用編寫一個精簡的聚合平臺,將抓取好的文章內(nèi)容展示出來。

上一篇文章《手把手教你如何用Crawlab構建技術文章聚合平臺(一)》介紹了如何使用搭建Crawlab的運行環(huán)境,并且將Puppeteer與Crawlab集成,對掘金、SegmentFault、CSDN進行技術文章的抓取,最后可以查看抓取結果。本篇文章將繼續(xù)講解如何利用Flask+Vue編寫一個精簡的聚合平臺,將抓取好的文章內(nèi)容展示出來。

文章內(nèi)容爬蟲

首先,我們需要對爬蟲部分做點小小的補充。上篇文章中我們只編寫了抓取文章URL的爬蟲,我們還需要抓取文章內(nèi)容,因此還需要將這部分爬蟲編寫了。上次爬蟲的結果collection全部更改為results,文章的內(nèi)容將以content字段保存在數(shù)據(jù)庫中。

經(jīng)分析知道每個技術網(wǎng)站的文章頁都有一個固定標簽,將該標簽下的HTML全部抓取下來就OK了。具體代碼分析就不展開了,這里貼出具體代碼。

const puppeteer = require("puppeteer");
const MongoClient = require("mongodb").MongoClient;

(async () => {
  // browser
  const browser = await (puppeteer.launch({
    headless: true
  }));

  // page
  const page = await browser.newPage();

  // open database connection
  const client = await MongoClient.connect("mongodb://192.168.99.100:27017");
  let db = await client.db("crawlab_test");
  const colName = process.env.CRAWLAB_COLLECTION || "results";
  const col = db.collection(colName);
  const col_src = db.collection("results");

  const results = await col_src.find({content: {$exists: false}}).toArray();
  for (let i = 0; i < results.length; i++) {
    let item = results[i];

    // define article anchor
    let anchor;
    if (item.source === "juejin") {
      anchor = ".article-content";
    } else if (item.source === "segmentfault") {
      anchor = ".article";
    } else if (item.source === "csdn") {
      anchor = "#content_views";
    } else {
      continue;
    }

    console.log(`anchor: ${anchor}`);

    // navigate to the article
    try {
      await page.goto(item.url, {waitUntil: "domcontentloaded"});
      await page.waitFor(2000);
    } catch (e) {
      console.error(e);
      continue;
    }

    // scrape article content
    item.content = await page.$eval(anchor, el => el.innerHTML);

    // save to database
    await col.save(item);
    console.log(`saved item: ${JSON.stringify(item)}`)
  }

  // close mongodb
  client.close();

  // close browser
  browser.close();

})();

然后將該爬蟲按照前一篇文章的步驟部署運行爬蟲,就可以采集到詳細的文章內(nèi)容了。

文章內(nèi)容爬蟲的代碼已經(jīng)更新到Github了。

接下來,我們可以開始對這些文章做文章了。

前后端分離

目前的技術發(fā)展來看,前后端分離已經(jīng)是主流:一來前端技術越來越復雜,要求模塊化、工程化;二來前后端分離可以讓前后端團隊分工協(xié)作,更加高效地開發(fā)應用。由于本文的聚合平臺是一個輕量級應用,后端接口編寫我們用Python的輕量級Web應用框架Flask,前端我們用近年來大紅大紫的上手容易的Vue。

Flask

Flask被稱為Micro Framework,可見其輕量級,幾行代碼便可以編寫一個Web應用。它靠Extensions插件來擴展其特定功能,例如登錄驗證、RESTful、數(shù)據(jù)模型等等。這個小節(jié)中我們將搭建一個REST風格的后臺API應用。

安裝

首先安裝相關的依賴。

pip install flask flask_restful flask_cors pymongo
基本應用

安裝完成后我們可以新建一個app.py文件,輸入如下代碼

from flask import Flask
from flask_cors import CORS
from flask_restful import Api

# 生成Flask App實例
app = Flask(__name__)

# 生成API實例
api = Api(app)

# 支持CORS跨域
CORS(app, supports_credentials=True)

if __name__ == "__main__":
    app.run()

命令行中輸入python app.py就可以運行這個基礎的Flask應用了。

編寫API

接下來,我們需要編寫獲取文章的接口。首先我們簡單分析一下需求。

這個Flask應用要實現(xiàn)的功能為:

從數(shù)據(jù)庫中獲取抓取到的文章,將文章ID、標題、摘要、抓取時間返回給前端做文章列表使用;

對給定文章ID,從數(shù)據(jù)庫返回相應文章內(nèi)容給前端做詳情頁使用。

因此,我們需要實現(xiàn)上述兩個API。下面開始編寫接口。

列表接口

app.py中添加如下代碼,作為列表接口。

class ListApi(Resource):
    def get(self):
        # 查詢
        items = col.find({"content": {"$exists": True}}).sort("_id", DESCENDING).limit(40)

        data = []
        for item in items:
            # 將pymongo object轉(zhuǎn)化為python object
            _item = json.loads(json_util.dumps(item))

            data.append({
                "_id": _item["_id"]["$oid"],
                "title": _item["title"],
                "source": _item["source"],
                "ts": item["_id"].generation_time.strftime("%Y-%m-%d %H:%M:%S")
            })
            
        return data
詳情接口

同樣的,在app.py中輸入如下代碼。

class DetailApi(Resource):
    def get(self, id):
        item = col.find_one({"_id": ObjectId(id)})
        
        # 將pymongo object轉(zhuǎn)化為python object
        _item = json.loads(json_util.dumps(item))
        
        return {
            "_id": _item["_id"]["$oid"],
            "title": _item["title"],
            "source": _item["source"],
            "ts": item["_id"].generation_time.strftime("%Y-%m-%d %H:%M:%S"),
            "content": _item["content"]
        }
映射接口

編寫完接口,我們需要將它們映射到對應到URL中。

api.add_resource(ListApi, "/results")
api.add_resource(DetailApi, "/results/")
完整代碼

以下是完整的Flask應用代碼,很簡單,實現(xiàn)了文章列表和文章詳情兩個功能。接下來,我們將開始開發(fā)前端的部分。

import json

from bson import json_util, ObjectId
from flask import Flask, jsonify
from flask_cors import CORS
from flask_restful import Api, Resource
from pymongo import MongoClient, DESCENDING

# 生成Flask App實例
app = Flask(__name__)

# 生成MongoDB實例
mongo = MongoClient(host="192.168.99.100")
db = mongo["crawlab_test"]
col = db["results"]

# 生成API實例
api = Api(app)

# 支持CORS跨域
CORS(app, supports_credentials=True)


class ListApi(Resource):
    def get(self):
        # 查詢
        items = col.find({}).sort("_id", DESCENDING).limit(20)

        data = []
        for item in items:
            # 將pymongo object轉(zhuǎn)化為python object
            _item = json.loads(json_util.dumps(item))

            data.append({
                "_id": _item["_id"]["$oid"],
                "title": _item["title"],
                "source": _item["source"],
                "ts": item["_id"].generation_time.strftime("%Y-%m-%d %H:%M:%S")
            })

        return data


class DetailApi(Resource):
    def get(self, id):
        item = col.find_one({"_id": ObjectId(id)})

        # 將pymongo object轉(zhuǎn)化為python object
        _item = json.loads(json_util.dumps(item))

        return {
            "_id": _item["_id"]["$oid"],
            "title": _item["title"],
            "source": _item["source"],
            "ts": item["_id"].generation_time.strftime("%Y-%m-%d %H:%M:%S"),
            "content": _item["content"]
        }


api.add_resource(ListApi, "/results")
api.add_resource(DetailApi, "/results/")

if __name__ == "__main__":
    app.run()

運行python app.py,將后臺接口服務器跑起來。

Vue

Vue近年來是熱得發(fā)燙,在Github上已經(jīng)超越React,成為三大開源框架(React,Vue,Angular)中star數(shù)最多的項目。相比于React和Angular,Vue非常容易上手,既可以雙向綁定數(shù)據(jù)快速開始構建簡單應用,又可以利用Vuex單向數(shù)據(jù)傳遞構建大型應用。這種靈活性是它受大多數(shù)開發(fā)者歡迎的原因之一。

為了構建一個簡單的Vue應用,我們將用到vue-cli3,一個vue項目的腳手架。首先,我們從npm上安裝腳手架。

安裝vue-cli3
yarn add @vue/cli

如果你還沒有安裝yarn,執(zhí)行下列命令安裝。

npm i -g yarn
創(chuàng)建項目

接下來,我們需要用vue-cli3構建一個項目。執(zhí)行以下命令。

vue create frontend

命令行中會彈出下列選項,選擇default。

? Please pick a preset: (Use arrow keys)
? default (babel, eslint) 
  preset (vue-router, vuex, node-sass, babel, eslint, unit-jest) 
  Manually select features 

然后vue-cli3會開始準備構建項目必要的依賴以及生成項目結構。

此外,我們還需要安裝完成其他功能所需要的包。

yarn add axios
文章列表頁面

views目錄中創(chuàng)建一個List.vue文件,寫入下列內(nèi)容。





其中,引用了axios來與API進行ajax交互,這里獲取的是列表接口。布局用來經(jīng)典的雙圣杯布局。methods中的showArticle方法接收id參數(shù),將頁面跳轉(zhuǎn)至詳情頁。

文章詳情頁面

views目錄中,創(chuàng)建Detail.vue文件,并輸入如下內(nèi)容。





這個頁面也是經(jīng)典的雙圣杯布局,中間占40%。由API獲取的文章內(nèi)容輸出到content中,由v-html綁定。這里其實可以做進一步的CSS優(yōu)化,但作者太懶了,這個任務就交給讀者來實現(xiàn)吧。

添加路由

編輯router.js文件,將其修改為以下內(nèi)容。

import Vue from "vue"
import Router from "vue-router"
import List from "./views/List"
import Detail from "./views/Detail"

Vue.use(Router)

export default new Router({
  mode: "hash",
  base: process.env.BASE_URL,
  routes: [
    {
      path: "/",
      name: "List",
      component: List
    },
    {
      path: "/:id",
      name: "Detail",
      component: Detail
    }
  ]
})
運行前端

在命令行中輸入以下命令,打開http://localhost:8080就可以看到文章列表了。

npm run serve
最終效果

最后的聚合平臺效果截屏如下,可以看到基本的樣式已經(jīng)出來了。

總結

本文在上一篇文章《手把手教你如何用Crawlab構建技術文章聚合平臺(一)》的基礎上,介紹了如何利用Flask+Vue和之前抓取的文章數(shù)據(jù),搭建一個簡易的技術文章聚合平臺。用到的技術很基礎,當然,肯定也還有很多需要優(yōu)化和提升的空間,這個就留給讀者和各位大佬吧。

Github

tikazyq/crawlab

tikazyq/tech-news

如果感覺Crawlab還不錯的話,請加作者微信拉入開發(fā)交流群,大家一起交流關于Crawlab的使用和開發(fā)。

文章版權歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/43418.html

相關文章

  • 爬蟲平臺Crawlab v0.2發(fā)布

    摘要:是一個專注于爬蟲的集成了爬蟲管理任務調(diào)度任務監(jiān)控數(shù)據(jù)分析等模塊的分布式爬蟲管理平臺,非常適合對爬蟲管理爬蟲工程化有要求的開發(fā)者及企業(yè)。從目前開源的框架來看,大部分爬蟲平臺是以為核心,因此只能支持框架的爬蟲,而不僅支持,還支持其他框架的爬蟲。 showImg(https://segmentfault.com/img/remote/1460000019143107?w=2559&h=112...

    yiliang 評論0 收藏0
  • 把手你如何用Crawlab構建技術文章聚合平臺(一)

    摘要:本文將介紹如何使用和抓取主流的技術博客文章,然后用搭建一個小型的技術文章聚合平臺。是谷歌開源的基于和的自動化測試工具,可以很方便的讓程序模擬用戶的操作,對瀏覽器進行程序化控制。相對于,是新的開源項目,而且是谷歌開發(fā),可以使用很多新的特性。 背景 說到爬蟲,大多數(shù)程序員想到的是scrapy這樣受人歡迎的框架。scrapy的確不錯,而且有很強大的生態(tài)圈,有gerapy等優(yōu)秀的可視化界面。但...

    Jeffrrey 評論0 收藏0
  • 把手你如何用Crawlab構建技術文章聚合平臺(一)

    摘要:本文將介紹如何使用和抓取主流的技術博客文章,然后用搭建一個小型的技術文章聚合平臺。是谷歌開源的基于和的自動化測試工具,可以很方便的讓程序模擬用戶的操作,對瀏覽器進行程序化控制。相對于,是新的開源項目,而且是谷歌開發(fā),可以使用很多新的特性。 背景 說到爬蟲,大多數(shù)程序員想到的是scrapy這樣受人歡迎的框架。scrapy的確不錯,而且有很強大的生態(tài)圈,有gerapy等優(yōu)秀的可視化界面。但...

    LinkedME2016 評論0 收藏0
  • [爬蟲手記] 我是如何在3分鐘內(nèi)開發(fā)完一個爬蟲的

    摘要:前言開發(fā)爬蟲是一件有趣的事情。的可配置爬蟲是基于的,因此天生是支持并發(fā)的。遵守協(xié)議這個默認是開啟的。的可配置爬蟲降低了爬蟲的開發(fā)時間,增加了爬蟲開發(fā)效率,完善了工程化水平,將爬蟲工程師從日常的繁瑣配置工作中解放出來。 前言 開發(fā)爬蟲是一件有趣的事情。寫一個程序,對感興趣的目標網(wǎng)站發(fā)起HTTP請求,獲取HTML,解析HTML,提取數(shù)據(jù),將數(shù)據(jù)保存到數(shù)據(jù)庫或者存為CSV、JSON等格式,再...

    sushi 評論0 收藏0
  • [爬蟲手記] 我是如何在3分鐘內(nèi)開發(fā)完一個爬蟲的

    摘要:前言開發(fā)爬蟲是一件有趣的事情。的可配置爬蟲是基于的,因此天生是支持并發(fā)的。的可配置爬蟲降低了爬蟲的開發(fā)時間,增加了爬蟲開發(fā)效率,完善了工程化水平,將爬蟲工程師從日常的繁瑣配置工作中解放出來。前言 開發(fā)爬蟲是一件有趣的事情。寫一個程序,對感興趣的目標網(wǎng)站發(fā)起HTTP請求,獲取HTML,解析HTML,提取數(shù)據(jù),將數(shù)據(jù)保存到數(shù)據(jù)庫或者存為CSV、JSON等格式,再用自己熟悉的語言例如Python對...

    YorkChen 評論0 收藏0

發(fā)表評論

0條評論

zhunjiee

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<