<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          快速獲取數(shù)據(jù)集的秘訣居然是……

          共 10472字,需瀏覽 21分鐘

           ·

          2021-06-01 08:10

          很久很久沒(méi)有動(dòng)手寫點(diǎn)什么了,近期有幸參加了 ModelArts 開(kāi)發(fā)者社區(qū)組織的關(guān)于 AIGallery 的會(huì)議,AIGallery ,這是一個(gè)開(kāi)放的平臺(tái),在這里可以學(xué)習(xí)和分享算法、模型、數(shù)據(jù)、Notebook、文章、課程、論文……從AI小白到大神的成長(zhǎng)之路(PS:可惜不才沒(méi)有上道,依舊是小白)。因此,希望在這里也能記錄下自己的成長(zhǎng)之路,給大家?guī)?lái)我以為好用的數(shù)據(jù)集生成之道,獻(xiàn)丑了!

          前言

          【FBI Warning:本方法目前只局限于從某度圖片獲取數(shù)據(jù)且非常適合圖像分類但不一定適用于實(shí)際應(yīng)用場(chǎng)景!!!】 前端時(shí)間想體驗(yàn)一下零基礎(chǔ)體驗(yàn)美食分類的AI應(yīng)用開(kāi)發(fā),需要一個(gè)美食數(shù)據(jù)集,因此找了一些工具來(lái)獲取我想要的美食圖片,最終選定了 Github 上某個(gè)前端項(xiàng)目來(lái)批量下載指定關(guān)鍵字的圖片到本地。本文將詳細(xì)介紹那一百來(lái)行的代碼究竟有何“魔力”能夠助我一臂之力從某度下載大量的圖片。

          代碼

          首先,先介紹一下源代碼來(lái)源:tangzihan-git/baiduImg-spider ,  這是一份托管在大名鼎鼎的全球最大同性交友網(wǎng)站 Github 上的“開(kāi)源”代碼,雖然作者不曾定義該項(xiàng)目的 License ,姑且認(rèn)為可以直接拿過(guò)來(lái)用。當(dāng)然如果要將代碼拷貝到本地,我們可能需要用到 Git 這個(gè)軟件。廢話不多說(shuō),先看看代碼。

          目錄結(jié)構(gòu)

          從目錄結(jié)構(gòu)來(lái)看,出去 Git 忽略配置文件 .gitignore、自述說(shuō)明文檔 README.md 以及前端 npm 包依賴文件 package.json,核心文件也就兩個(gè):baidu-img.js 用來(lái)訪問(wèn)網(wǎng)頁(yè)并輸入關(guān)鍵字獲取圖片列表, imgload.js 用來(lái)下載圖片。我們查看 package.json 就能看到所需的 npm 包,這里的 npm 包可以理解為引入外部的依賴,讓我們的程序能夠快速獲得某種能力。package.json 如下:

          {
            "name""spider",
            "version""1.0.0",
            "description""",
            "main""req.js",
            "scripts": {
              "test""echo \"Error: no test specified\" && exit 1",
              "start":"node baidu-img"
            },
            "keywords": [],
            "author""",
            "license""ISC",
            "dependencies": {
              "axios""^0.19.2",
              "bufferutil""^4.0.1",
              "cheerio""^1.0.0-rc.3",
              "optimist""^0.6.1",
              "puppeteer""^5.2.1",
              "utf-8-validate""^5.0.2"
            }
          }

          dependencies 字段中定義了我們依賴的外部包,其中axios是前端項(xiàng)目中常用的基于Promise的HTTP客戶端,可用于瀏覽器和node.js,我們可以理解為以前 JQuey 中的 Ajax ;Puppeteer是谷歌開(kāi)源的可調(diào)用高級(jí)API來(lái)通過(guò)DevTools協(xié)議控制無(wú)頭Chrome或Chromium的工具,這里用來(lái)提供一個(gè)無(wú)頭的瀏覽器進(jìn)行訪問(wèn)指定網(wǎng)頁(yè)。至于其它的依賴包,代碼中并沒(méi)有用到,我們可以先忽略。接下來(lái),看看代碼實(shí)現(xiàn)。

          關(guān)鍵代碼

          • baidu-img.js
          // 引入依賴
          const puppeteer = require('puppeteer')
          const url = require('url')
          const path = require('path')
          const imgLoad = require('./imgload')

          // 定義訪問(wèn)地址
          const httpUrl = 'https://image.baidu.com/'
          var argv = require('optimist').argv;

          // 入?yún)?br>let options = {
              word:argv.word || '圖片',
              num:argv.num || 60,
              dir:argv.dir || 'images',
              delay:argv.delay || 600

          }
          ;( async function(){
              // Puppeteer 配置
              let config = {
                  headless:true,//無(wú)界面操作 ,false表示有界面
                  defaultViewport:{
                      width:820,
                      height:1000,
                  },
              }
              // 運(yùn)行瀏覽器
              let browser = await puppeteer.launch(config)
              // 打開(kāi) https://image.baidu.com/
              let page = await browser.newPage()
              await page.goto(httpUrl)
              // 定位到輸入框并輸入關(guān)鍵字,點(diǎn)擊搜索
              // 這里的 #kw .s_newBtn .main_img 都是頁(yè)面的元素
              await page.focus('#kw')
              await page.keyboard.sendCharacter(options.word);//搜索詞
              await page.click('.s_newBtn')
              //頁(yè)面搜索跳轉(zhuǎn) 執(zhí)行的邏輯
              page.on('load',async ()=>{
                  console.warn('正在為你檢索【'+options.word+'】圖片請(qǐng)耐心等待...');
                  await page.evaluate((options)=>{
                      ///獲取當(dāng)前窗口高度  處理懶加載
                      let height = document.body.offsetHeight
                      let timer = setInterval(()=>{
                          //窗口每次滾動(dòng)當(dāng)前窗口的2倍
                          height=height*2
                          window.scrollTo(0,height);
                      },2000)

                      window.onscroll=function(){
                          let arrs = document.querySelectorAll('.main_img')
                          //符合指定圖片數(shù)
                          if(arrs.length>=options.num){
                              clearInterval(timer)
                              console.log(`為你搜索到${arrs.length}張【${options.word}】相關(guān)的圖片\n準(zhǔn)備下載(${options.num})張`);
                          }  
                      }
                  },options)
              })

              await page.on('console',async msg=>{
                  console.log(msg.text());
                  //提取圖片的src
                  let res = await page.$$eval('.main_img',eles=>eles.map((e=>e.getAttribute('src'))))
                  res.length = options.num
                  res.forEach(async (item,i)=>{
                      // 下載圖片
                      await page.waitFor(options.delay*i)//延遲執(zhí)行
                      await imgLoad(item,options.dir)

                  })
                  // 關(guān)閉瀏覽器
                  await browser.close()
                  
              })
          })()

          以上的代碼,類似于人的操作:打開(kāi)網(wǎng)頁(yè)-->輸入關(guān)鍵字-->點(diǎn)擊搜索-->瀏覽結(jié)果并下載。

          • imgload.js
          const path = require('path')
          const fs = require('fs')
          const http  = require('http')
          const https = require('https')
          const {promisify} = require('util')
          const writeFile = promisify(fs.writeFile);

          module.exports = async (src,dir)=>{
              if(/\.(jpg|png|jpeg|gif)$/.test(src)){
                  await urlToImg(src,dir)
              } else {
                  await base64ToImg(src,dir)
              }
          }


          const urlToImg = (url,dir)=>{
              const mod = /^https:/.test(url)?https:http
              const ext = path.extname(url)
              fs.mkdir(dir,function(err){
                  if(!err){
                      console.log('成功創(chuàng)建目錄')
                  }
              })
              const file = path.join(dir, `${Date.now()}${ext}`)
              //請(qǐng)求圖片路徑下載圖片
              mod.get(url,res=>{
                  res.pipe(fs.createWriteStream(file))
                  .on('finish',()=>{
                      console.log(file+' download successful');
                  })
              })
            
          }

          //base64-download
          const base64ToImg = async function(base64Str,dir){
              //data:image/jpg;base64,/fdsgfsdgdfghdfdfh
              try{
                  const matches = base64Str.match(/^data:(.+?);base64,(.+)$/)
                  const ext = matches[1].split('/')[1].replace('jpeg','jpg')//獲取后綴
                  fs.mkdir(dir,function(err){
                      if(!err){
                          console.log('成功創(chuàng)建'+dir+'目錄')
                      }
                  })
                  const file = path.join(dir, `${Date.now()}.${ext}`)
                  const content = matches[2]
                  await writeFile(file,content,'base64')
                  console.log(file+' download successful');
                
              }catch(e){
                  console.log(e);
              }
          }

          不得不佩服作者的鬼斧神工,一百來(lái)行代碼就解決了我的需求!

          運(yùn)行

          按照前端的慣例,一般需要安裝一下 NodeJS ,好比業(yè)界流傳的“無(wú)Node不前端”的調(diào)侃,NodeJS 是 JavaScript 的運(yùn)行時(shí),提供了服務(wù)端的能力。我們把代碼下載下來(lái)之后,先安裝 NodeJS,接著運(yùn)行npm install安裝依賴,再運(yùn)行node .\baidu-img.js --word=反光衣 --num=1000 --dir=./dataset/反光衣 --delay=200就能夠下載1000張反光衣的圖片了,當(dāng)然,往往理想是豐滿的,現(xiàn)實(shí)往往需要我們?cè)俅蚰ゴ蚰ァ?/p>

          好像就這么簡(jiǎn)單,分享到此結(jié)束……



          最后,如果您沒(méi)有數(shù)據(jù)集,可以來(lái) AIGallery 逛一逛,說(shuō)不定就有合適的數(shù)據(jù)集,甚至可以直接用來(lái)訓(xùn)練!我在 huaweicloud.ai ,期待您的參與!


          點(diǎn)擊閱讀原文了解更多
          瀏覽 20
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  8x8x最新地址 | 欧美色图中文字幕 | 天天干天天舔 | 久久午夜无码鲁丝午夜精品 | 午夜成人大片 |