天天看點

Python爬蟲實戰,argparse子產品,Github使用者粉絲資料爬蟲

前言

主要目标是爬取Github上指定使用者的粉絲資料以及對爬取到的資料進行一波簡單的可視化分析。

讓我們愉快地開始吧~

開發工具

Python版本:3.6.4

相關子產品:

bs4子產品;

requests子產品;

argparse子產品;

pyecharts子產品;

以及一些python自帶的子產品。

環境搭建

安裝Python并添加到環境變量,pip安裝需要的相關子產品即可。

資料爬取

感覺好久沒用beautifulsoup了,是以今天就用它來解析網頁進而獲得我們自己想要的資料呗。以我自己的賬戶為例:

我們先抓取所有關注者的使用者名,它在類似如下圖所示的标簽中:

用beautifulsoup可以很友善地提取它們:

'''獲得followers的使用者名'''
def getfollowernames(self):
    print('[INFO]: 正在擷取%s的所有followers使用者名...' % self.target_username)
    page = 0
    follower_names = []
    headers = self.headers.copy()
    while True:
        page += 1
        followers_url = f'https://github.com/{self.target_username}?page={page}&tab=followers'
        try:
            response = requests.get(followers_url, headers=headers, timeout=15)
            html = response.text
            if 've reached the end' in html:
                break
            soup = BeautifulSoup(html, 'lxml')
            for name in soup.find_all('span', class_='link-gray pl-1'):
                print(name)
                follower_names.append(name.text)
            for name in soup.find_all('span', class_='link-gray'):
                print(name)
                if name.text not in follower_names:
                    follower_names.append(name.text)
        except:
            pass
        time.sleep(random.random() + random.randrange(0, 2))
        headers.update({'Referer': followers_url})
    print('[INFO]: 成功擷取%s的%s個followers使用者名...' % (self.target_username, len(follower_names)))
    return follower_names
           

接着,我們就可以根據這些使用者名進入到他們的首頁來抓取對應使用者的詳細資料了,每個首頁連結的構造方式為:

https://github.com/ + 使用者名
例如: https://github.com/CharlesPikachu
           

我們想要抓取的資料包括:

同樣地,我們利用beautifulsoup來提取這些資訊:

for idx, name in enumerate(follower_names):
    print('[INFO]: 正在爬取使用者%s的詳細資訊...' % name)
    user_url = f'https://github.com/{name}'
    try:
        response = requests.get(user_url, headers=self.headers, timeout=15)
        html = response.text
        soup = BeautifulSoup(html, 'lxml')
        # --擷取使用者名
        username = soup.find_all('span', class_='p-name vcard-fullname d-block overflow-hidden')
        if username:
            username = [name, username[0].text]
        else:
            username = [name, '']
        # --所在地
        position = soup.find_all('span', class_='p-label')
        if position:
            position = position[0].text
        else:
            position = ''
        # --倉庫數, stars數, followers, following
        overview = soup.find_all('span', class_='Counter')
        num_repos = self.str2int(overview[0].text)
        num_stars = self.str2int(overview[2].text)
        num_followers = self.str2int(overview[3].text)
        num_followings = self.str2int(overview[4].text)
        # --貢獻數(最近一年)
        num_contributions = soup.find_all('h2', class_='f4 text-normal mb-2')
        num_contributions = self.str2int(num_contributions[0].text.replace('\n', '').replace(' ', ''). \
                            replace('contributioninthelastyear', '').replace('contributionsinthelastyear', ''))
        # --儲存資料
        info = [username, position, num_repos, num_stars, num_followers, num_followings, num_contributions]
        print(info)
        follower_infos[str(idx)] = info
    except:
        pass
    time.sleep(random.random() + random.randrange(0, 2))
           

資料可視化

這裡以我們自己的粉絲資料為例,大概1200條吧。

先來看看他們在過去一年裡送出的代碼次數分布吧:

送出最多的一位名字叫fengjixuchui,在過去一年一共有9437次送出。平均下來,每天都得送出20多次,也太勤快了。

再來看看每個人擁有的倉庫數量分布呗:

本以為會是條單調的曲線,看來低估各位了。

接着來看看star别人的數量分布呗:

再來看看這1000多個人擁有的粉絲數量分布呗:

簡單看了下,有不少小夥伴的followers數量比我還多。果然高手在民間。

文章到這裡就結束了,感謝你的觀看,Python小案例系列暫停更新,下個篇章将分享Python小工具系列