Magren

Magren

Idealist & Garbage maker 🛸
twitter
jike

使用Puppeteer爬取Github指南

介紹#

puppeteer 是一個由 Chrome 官方推出的 headless Chrome node 庫。它提供了一系列的 API,可以在無 UI 的情況下調用 Chrome 的功能,適用於爬蟲、自動化處理等各種場景。

使用#

安裝#

npm install puppeteer-chromium-resolver --save

生成 / 關閉瀏覽器#

 const browser = await (puppeteer.launch({
        args: ['--no-sandbox', 
        '--disable-setuid-sandbox'],
        //如果是訪問https頁面 此屬性會忽略https錯誤
        ignoreHTTPSErrors: true,
        headless: true, //改為true則是無頭模式,不顯示瀏覽器,在無界面的環境中運行 Chrome
  }));

  //關閉
  browser.close();

生成新的 tab 並且跳轉#

const page = await browser.newPage();
await page.goto('https://github.com/'+name+'?tab=repositories'); //跳轉到github某個用戶的倉庫頁

在控制台中執行函數( evaluate () )#

//獲取當頁的所有項目url,同時有下一頁倉庫的url的話也獲取
 const rep =  await page.evaluate(()=>{
        const url = document.querySelectorAll('.wb-break-all > a');
        const next = document.querySelector('.BtnGroup > a');
        let urlList = undefined;
        let nextUrl = undefined;
        if(url != null){
            urlList = Array.prototype.map.call(url,(item)=>{
                return item.href;
            })
        }
        if(next!=null&&next.outerText==='Next'){
            nextUrl = next.href;
        }
        return {
            urlList:urlList,
            nextUrl:nextUrl
        }
  });

獲取頁面元素#

const el = await page.$(selector)

點擊元素#

await el.click()

輸入內容#

await el.type(text)

爬取 Github 中的數據#

使用了 express,因個人需要爬取了指定用戶的 follower 數,以及 commit 過的日期以及當天 commit 的次數,還有爬取每一個公開的項目的 url、項目名、commit 數以及 star 數,拼接後返回 json。

項目地址:getGithub

調用例子:

http://localhost:4000/getAllContributions/Magren0321

返回數據示例:
test.png

踩到的坑#

在爬取每一年的 contributions 數的時候,獲取其元素的屬性失敗,因為其data-date以及data-count等屬性是 github 自己定義的屬性,無法直接獲取,這裡必須得使用getAttribute() 方法。

同時 Attribute 中還有 setAttribute () 和 removeAttribute (),分別是設置和移除節點原型中不存在的屬性。

//獲取日期以及當天的提交數
async function getDateList(yearData,page){
    await page.goto(yearData);
    const dateList = await page.evaluate(()=>{
        const date = document.querySelectorAll('.ContributionCalendar-day');
        const datelist = [];
        for(let item of date){
            if(item.getAttribute('data-count')!=0&&item.getAttribute('data-count')!=null){
                datelist.push({
                    data_date: item.getAttribute('data-date'),
                    data_count: item.getAttribute('data-count')
                })
            }
        }
      
        return datelist;
    })
    return dateList;
}

Github api 還有一些奇奇怪怪的地方就不總結了……
比如返回一個空的數組,但是我輸出其 length 居然是 2,用直接請求發現是裡面放了兩個換行😵
只能找多幾個數據測試😔

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。