node爬蟲:送你一大波美腿圖

決定送你們一套美圖。可是授之以魚不如授之以漁,咱們就來使用node實現個小爬蟲去爬取各類美女javascript

來吧,咱們先來看看今天的目標: mmjpg.com的美腿頻道下的圖片前端

在開始以前先來科普科普java

美腿是形容女性美麗、性感、修長的腿形美。美腿能夠分爲白璧無瑕的大腿美、晶瑩剔透的小腿美、細微的美足、健康明朗的腿形美。所謂腿健美,是指腿部的線條美。腿的長短與肥瘦是決定腿部美醜的兩大因素。

1、實現步驟

  1. 肯定目標頁面
  2. 使用superagent庫來獲取頁面
  3. 分析頁面結構,使用cheerio 獲取有效信息
  4. 保存圖片到本地
  5. 開擼
  6. 不斷優化

2、開始編寫爬取妹子圖的爬蟲

下載這個小項目須要使用的庫node

npm i superagent cheerio fs-extra --save

這兒咱們用到了superagent cheerio fs-extra這三個庫git

  • superagent 是nodejs裏一個很是方便的客戶端請求代理模塊
  • cheerio:爲服務器特別定製的,快速、靈活、實施的jQuery核心實現
  • fs-extra: 豐富了fs模塊,同時支持async/await

2.1 請求URL獲取HTML

使用superagent發起請求並打印出頁面內容github

const request = require('superagent')
const cheerio = require('cheerio')
const fs = require('fs-extra')

let url = 'http://www.mmjpg.com/tag/meitui/'

request
  .get(url + '1')
  .then(function (res) {
    console.log(res.text)
  })

// 你就能夠看見HTML內容打印到了控制檯

2.2 分析頁面結構

如今咱們就須要分析頁面結構,而後使用cheerio來操做了,你沒用過cheerio沒關係它的語法和jQuery基本同樣。做爲前端,在開發者工具中分析頁面應該是屢見不鮮,手到擒來。這兒就很少說了,記住咱們的目標是找出須要的節點獲取到有效信息就好npm

咱們能夠發現須要的東西都在class爲pic那個div下的列表中,如今咱們就可使用cheerio來獲取bash

...
async function getUrl() {
    const res = await request.get(url + 1)
    const $ = cheerio.load(res.text)
    $('.pic li').each(function(i, elem) {
        const href = $(this).find('a').attr('href')
        const title = $(this).find('.title').text()
        console.log(title, href)
    })
}

getUrl()

/* console
$ node app.js
大美女尹菲開檔網襪寫真使人眼花繚亂 http://www.mmjpg.com/mm/1230
宅男女神豐滿誘人的胴體使人想入非非 http://www.mmjpg.com/mm/1164
性感美女浴室寫真高聳的酥胸誘惑十足 http://www.mmjpg.com/mm/1162
長相清純甜美的97年妹子苗條美腿圖片 http://www.mmjpg.com/mm/1157
麗質美女柔美修長美腿帶給你曼妙感覺 http://www.mmjpg.com/mm/1153
容貌似楊冪的美女馨怡美腿極致誘惑圖 http://www.mmjpg.com/mm/1148
絲襪美腿誘惑!甜美女神楊晨晨私房套圖 http://www.mmjpg.com/mm/1130
性感美女劉鈺兒透視內衣私密照真撩人 http://www.mmjpg.com/mm/1127
膚白貌美的模特李晨晨十分惹人憐愛 http://www.mmjpg.com/mm/1126
萌妹林美惠子穿黑絲浴室私房寫真福利 http://www.mmjpg.com/mm/1124
美女趙小米修長雙腿絲襪寫真能玩幾年 http://www.mmjpg.com/mm/1111
*/

2.3 分析URL地址

在不少時候咱們都須要分析URL,就像點擊不一樣的頁碼觀察URL變化 http://www.mmjpg.com/tag/meit...,咱們能夠很容易發現頁碼對應爲URL最後的數字。查看mmjpg.com的美腿頻道咱們能夠發現它一共有10頁內容,咱們就不寫代碼判斷頁數了直接寫死爲10。固然了這兒你能夠本身實現動態判斷總頁數,就當是留的小練習吧。服務器

async function getUrl() {
  let linkArr = []
  for (let i = 1; i <= 10; i++) {
    const res = await request.get(url + i)
    const $ = cheerio.load(res.text)
    $('.pic li').each(function (i, elem) {
      let link = $(this).find('a').attr('href')
      linkArr.push(link)
    })
  }
  return linkArr
}

2.4 獲取圖片地址

如今咱們已經能獲取到圖集的URL了。在上一步咱們獲取圖集URL的時候是把頁碼寫死了的,這是由於那個頁碼不是動態的,然而每一個圖集的圖片頁數是不同的,這兒咱們就須要動態判斷了。進入圖集後,切換圖片的頁碼URL也會跟着變,如今這個URL就是每張圖片頁面的URL。咱們只須要獲取最後一個頁面的頁碼, 從 1 開始歷遍,和咱們上面獲取的URL拼接在一塊兒就是每張圖片的頁面地址啦!app

獲取到單個圖片URL後,咱們能夠經過圖片的src屬性去拿到真實的圖片地址,而後實現下載保存

async function getPic(url) {
  const res = await request.get(url)
  const $ = cheerio.load(res.text)
  // 以圖集名稱來分目錄
  const dir = $('.article h2').text()
  console.log(`建立${title}文件夾`)
  await fs.mkdir(path.join(__dirname, '/mm', title))
  const pageCount = parseInt($('#page .ch.all').prev().text())
  for (let i = 1; i <= pageCount; i++) {
    let pageUrl = url + '/' + i
    const data = await request.get(pageUrl)
    const _$ = cheerio.load(data.text)
    // 獲取圖片的真實地址
    const imgUrl = _$('#content img').attr('src')
    download(dir, imgUrl) // TODO
  }
}

2.5 保存圖片到本地

如今咱們就來實現下載保存圖片的方法,這兒咱們使用了stream(流) 來保存圖片

function download(dir, imgUrl) {
  console.log(`正在下載${imgUrl}`)
  const filename = imgUrl.split('/').pop()  
  const req = request.get(imgUrl)
    .set({ 'Referer': 'http://www.mmjpg.com' }) // mmjpg.com根據Referer來限制訪問
  req.pipe(fs.createWriteStream(path.join(__dirname, 'mm', dir, filename)))
}

ok,如今咱們就來把以前寫的各個功能的函數連起來

async function init(){
  let urls = await getUrl()
  for (let url of urls) {
    await getPic(url)
  }
}

init()

運行該文件,你就能夠看終端打印出入下信息,你的文件夾中也多了好多美女圖喲!開不開心?嗨不嗨皮?

前方高能

一大波美女來襲

好吧~不刪掉經過不了

源碼:https://github.com/ogilhinn/m...

到此這個小爬蟲就算寫完了,可是這只是一個很簡陋的爬蟲,還有不少須要改進的地方

你還能夠加入不少東西讓它更健壯,如:

  • 使用多個userAgent
  • 不斷更換代理ip
  • 下降爬蟲的速度,加個sleep()
  • ……

如何讓它更健壯、如何應對反爬蟲策略這些留着之後再講吧

3、參考連接

你們能夠關注個人公衆號,一塊兒玩耍。有技術乾貨也有扯淡亂談,關注回覆[888]還有意外驚喜領取

JavaScript之禪

左手代碼右手磚,拋磚引玉

相關文章
相關標籤/搜索