puppeteer進階版_爬取小說站

寫爬蟲抓取頁面是否是還須要等待頁面有數據了才能抓取,那麼頁面渲染的這段時間(雖然不長但架不住多啊)是否是能夠省去呢

時間要好好的利用起來

基礎不太瞭解的能夠參考我這篇簡單使用的文章

使用puppeteer抓取接口攔截ajax數據

這裏有小夥伴就要說了我都知道接口了直接去請求不就完了嗎,python,node,axios,原生的ajax那個不行啊

哈哈,那要是接口參數中有隨機數呢,有隨機時間點呢,有隨機時間戳和uuid再混起來呢

分分鐘懷疑人生

來看小說站的接口參數

我們準備抓取的信息

圖中標記的自上往下分別是:php

  1. 書籍id
  2. 要抓取的信息
  3. 接口
  4. 接口地址

clipboard.png

接口數據

clipboard.png

懷疑人生的時候到了,來看請求參數

  1. 首先是 post 請求
  2. 再來分析Form Data數據
  3. bookID和user_id都沒啥事
  4. timestamp這個參數是有必定間隔時間的時間戳
  5. 頭大的是這個, sign, 黑人問號臉(這是個啥)

clipboard.png

翻騰了很久找了一個js文件發現了sign的由來

  1. 仍是個md5加密的
  2. 那麼問題來了
  3. 這個r,經過這個接口能夠知道它就是bookid了
  4. 小問題是這個有固定間隔時間的timestamp怎麼獲取,喜歡等待的小夥伴能夠試試等等看,具體我也不知道,不過應該在10分鐘以上了
  5. 大問題是這個bookKey是個啥啊,找遍了也沒找到,我能怎麼辦,我也很絕望啊,沒辦法只能放大招了

clipboard.png
clipboard.png

來來來

官網的api能夠看到這麼幾個,哇,看到這哥幾個莫名的興奮啊,點過去再看看,就問你激動不激動

看到這裏我就很少囉嗦了,直接上代碼(詳細說明在註釋裏)

clipboard.png
clipboard.png

代碼最爲關鍵的地方截圖

clipboard.png

結果截圖

clipboard.png

忽然頓悟,都這樣了,試問頁面上還有啥是拿不到的,完整代碼

轉載請附上本文章地址

const puppeteer = require('puppeteer');
const mongodb = require('mongodb')
// mongoDB
const mongo_url = 'mongodb://127.0.0.1:27017/book'
const mongoClient = mongodb.MongoClient
// 休眠函數
function sleep(second) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(' enough sleep~');
        }, second);
    })
}
// 站點地址url
var url = `http://t.shuqi.com/route.php?pagename=route.php#!/ct/cover/bid/6070553`

class Parse {
  constructor() {
    this.page = null
    this.browser = null
    this.bookMessage = {}
  }
  async init() {
    // 構造瀏覽器對象
    // 顯示瀏覽器
    this.browser = await puppeteer.launch({
      'headless': false,
    });
    // 建立頁面
    this.page = await this.browser.newPage();
    // 模擬瀏覽器信息
    const UA = "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.119 Safari/537.36";
    await Promise.all([
        this.page.setUserAgent(UA),
        // 容許執行js腳本
        this.page.setJavaScriptEnabled(true),
        // 頁面視口大小
        this.page.setViewport({width: 1100, height: 1080}),
    ]);
    await this.getBook()
  }
  async getBook() {
    // 打開頁面
    await this.page.goto(url);
    let page = await this.page
    // 等待頁面請求完成
    page.on('requestfinished', request => {
      // 查看全部請求地址
      // console.log(request.url)
      // ajax
      if (request.resourceType == "xhr") {
        // 匹配所需數據的請求地址
        if(request.url.indexOf('http://walden1.shuqireader.com/webapi/book/info') != -1) {
          (async () => {
            try {
              // 獲取數據並轉爲json格式
              let res = await request.response();
              let result = await res.json();
              let res_data = result.data     
              // 接口數據中找到須要的數據      
              this.bookMessage = {                        
                'book_name': res_data.bookName,              
                'book_summary': res_data.desc,              
                'author_name': res_data.authorName,              
              }
              let data = await this.bookMessage
              mongoClient.connect(mongo_url, (err, db) => {                
                db.collection('shuqi_test').insert(data,(err, result) => {
                    if(err) {
                      console.log('鏈接失敗')
                    }
                    // 關閉瀏覽器            
                    this.browser.close()                    
                    // 關閉數據庫鏈接
                    db.close()
                  }
                )
              })
            } catch(err) {
              console.log(err)
            }
          })()
        }
      }
    });
  }
}

let parse = new Parse()
parse.init()
相關文章
相關標籤/搜索