1. 程式人生 > >Python - 爬蟲爬取和登陸github

Python - 爬蟲爬取和登陸github

用API搜尋GitHub中star數最多的前十個庫,並用post方法登陸並點選收藏


一 用API搜尋GitHub中star數最多的前十個庫

利用GitHub提供的API爬取前十個star數量最多的Python庫

    GitHub提供了很多專門為爬蟲準備的API介面,通過介面可以爬取到便捷,易處理的資訊。(這是GitHub官網的各種api介紹

    我將要使用的連結是https://api.github.com/search/repositories?q=language:python&sort=stars。 ‘language:’後是要搜尋的語言,‘sort=’後是搜尋的排序方式,這個連結以star數量返回前三十個Python庫的資訊。

    使用到的庫

import requests

    通過get請求到網頁的資訊

response = requests.get('https://api.github.com/search/repositories?q=language:python&sort=stars')
#檢測是否請求成功,若成功,狀態碼應該是200
if(response.status_code != 200):
    print('error: fail to request')

若我們自己點入上方的連結,會發現一個特別的網頁,沒有介面,只有由簡單的字元組成。

    仔細觀察,會發現字元和字典的結構是相同的,最上層是三個關鍵詞,其中 'items'關鍵詞儲存有一個List,裡面有多組字典資訊,每一個字典儲存有一個python庫的詳細資訊。

    所以直接提取相應資訊即可

#獲取的是一個json格式的字典物件
j = response.json()
#'items'下包括了前三十個庫的所有詳細資訊
items= j['items']

#儲存前十個資料
message = []
for i in range(10):
    pro = items[i]
    message.append(pro['full_name'])#庫的'作者/名字'
    #依次列印
    print('top%d:' % (i+1), pro['name'])#列印庫的名字

     列印結果:

top1: awesome-python
top2: system-design-primer
top3: models
top4: public-apis
top5: youtube-dl
top6: flask
top7: thefuck
top8: httpie
top9: django
top10: awesome-machine-learning

    完整程式碼:

'''
用於列印並返回前十個最受歡迎的庫
傳入的是搜尋的語言,這個程式需要傳入'python',
返回的是一個存有前十個庫的'作者名/庫名'的List
'''
def find_top10(language):
    #利用github提供的api介面進行搜尋
    response = requests.get(
        "https://api.github.com/search/repositories?q=language:%s&sort=stars"%(language))

    #檢測是否請求成功
    if(response.status_code != 200):
        print('error! in find_top10(): fail to request')
        return None

    #獲取的是一個json格式的字典物件
    j = response.json()
    #keyword 'items'下的包括了前三十個庫的所有詳細資訊
    progress = j['items']

    #儲存前十個資料
    message = []
    for i in range(10):
        pro = j['items'][i]
        message.append(pro['full_name'])
        #依次列印
        print('top%d:' % (i+1), pro['name'])
    return message

二 用post方法登陸GitHub

    先擼一擼post需要的東西。首先我們肯定要知道我們的url是什麼,其次我們得知道我們需要提交哪些資訊(data)

    我們先點開GitHub的登陸介面,嘗試著登陸,利用谷歌的“右鍵->檢查->network"檢視登陸時的資訊。

    找到了登陸需要使用的url,以及登陸時需要上傳的資訊(data

   但我們發現,Data中有一個authenticity_token,知乎也有這個東西,貌似是用來保證安全用的。但重點是,我們從哪兒去找這個值呢

    authenticity_token的值往往隱藏在上一級網頁

    果然,在登陸介面的網頁程式碼中找到了隱藏的authenticity_token資訊(記住這個方法

    

    我們根據上方資訊進行登陸:(authenticity_token值需要用爬蟲尋找而不能直接複製瀏覽器中的值!)

    用get方法獲取登陸介面的資訊,得到cookies以及authenticity_token

r1 = requests.get('https://github.com/login')

    soup = BeautifulSoup(r1.text, features='lxml')
     #獲取authenticity_token
    att = soup.find(name='input', attrs={'name': 'authenticity_token'}).get('value')
    #獲取cookies
    cookie = r1.cookies.get_dict()

    利用得到的資訊構造Data並登陸 

r2 = requests.post(
    'https://github.com/session',
    data={
        'commit': 'Sign in',
        'utf8': '✓',
        'authenticity_token': att,
        'login': username,
        'password': password
        },
    cookies=cookie
)
#返回登陸後的cookies可用於以登陸身份訪問GitHub
return r2.cookies.get_dict()

    完整程式碼: 

'''
用於登陸github的函式
傳入賬號密碼,登陸並返回登陸後的cookies
'''
def login(username, password):
    #get登陸頁面並獲取 authenticity_token 和 cookies(登陸需要)
    r1 = requests.get('https://github.com/login')

    if(r1.status_code != 200):
        print('error! in login(): fail to request')
        return None

    soup = BeautifulSoup(r1.text, features='lxml')
     #獲取authenticity_token
    att = soup.find(name='input', attrs={
                        'name': 'authenticity_token'}).get('value')
    #獲取cookies
    cookie = r1.cookies.get_dict()
    #利用獲取的資訊登陸github
    r2 = requests.post(
        'https://github.com/session',
        data={
            'commit': 'Sign in',
            'utf8': '✓',
            'authenticity_token': att,
            'login': username,
            'password': password
        },
        cookies=cookie
    )

    if(r2.status_code != 200):
        print('error! in login(): fail to request')
        return None
        
    print('successed login')
    return r2.cookies.get_dict()

三 用post方法收藏star數量最多的前十個python倉庫

    我們已經找到了這十個庫,也成功登陸了GitHub

    所以我們現在需要做的就是尋找收藏某個一個庫的方法

    我隨便點開了一個庫‘thefuck',可以在右上角找到star的按鈕

    於是我用登陸時同樣的方法,點選按鈕,並用谷歌分析資訊,

    成功的找到了post的url地址,以及需要提交的data

 

    我們又看到了熟悉的authenticity_token!真是麻煩啊,但我們已經學會了如何尋找這個值

    果然,我在這個網頁的程式碼裡面找到了隱藏的authenticity_token。

    所以我們需要用get方法得到這個網頁,並在網頁程式碼中找到這個值

    

    通過get獲取authenticity_token,這裡傳入了登陸之後得到的cookies

get2 = requests.get(
        'https://github.com/nvbn/thefuck',
        cookies=cookie
    )
    #更新cookies
    cookie = get2.cookies.get_dict()
    
    #得到authenticity_token
    soup2 = BeautifulSoup(get2.text, features='lxml')
    #據分析,star的authenticity_token是放於class屬性為unstarred js-social-form的塊中
    soup = soup2.find('form', {'class': 'unstarred js-social-form'})
    att2 = soup.find(name='input', attrs={
        'name': 'authenticity_token'}).get('value')

     提交post請求進行收藏,提交成功後便收藏成功

#提交Post請求,請求之後即收藏了該庫
r = requests.post(
    'https://github.com/nvbn/thefuck/star',
        data={
         'utf8': '✓',
        'authenticity_token': att2,
        'context': 'repository'
    },
    cookies=cookie
 )

    完整程式碼: 

'''
利用登陸的cookies點選star收藏專案

這裡我分析了某個庫的網頁程式碼,按鈕'star'中,提供了一‘authenticity_token’和一個用於post的連結(https://github.com/作者名/庫名/star),只要獲取‘authenticity_token’並用登陸的cookies訪問連結,即可實現點選該按鈕的同樣效果。

所以只需要傳入cookies 和 作者名/庫名即可
'''
def get_stared(cookie, name):
    #get到該庫的介面並得到用於 點選star的post提交的authenticity_token
    get2 = requests.get(
        #利用傳入的‘作者名/庫名’進行操作
        'https://github.com/%s'%(name),
        cookies=cookie
    )
    cookie = get2.cookies.get_dict()
    #檢驗請求情況
    if(response.status_code != 200):
        print('error! in get_stared(): get: fail to request')
        return None
    
    #得到authenticity_token
    soup2 = BeautifulSoup(get2.text, features='lxml')
    soup = soup2.find('form', {'class': 'unstarred js-social-form'})
    att2 = soup.find(name='input', attrs={
        'name': 'authenticity_token'}).get('value')

    #提交Post請求,請求之後即收藏了該庫
    r = requests.post(
        'https://github.com/%s/star'%(name),
        data={
            'utf8': '✓',
            'authenticity_token': att2,
            'context': 'repository'
        },
        cookies=cookie
    )
    #檢驗請求情況,這裡比較特殊,返回錯誤碼400的時候收藏成功
    if(response.status_code != 400):
        print('error! in get_stared(): get: fail to request')
        return None

全部程式碼:加入了執行需要的函式和句子

'''
1.利用爬蟲登陸github
2.搜所前十個最受歡迎的Python庫(star數作為排序標準)
3.並收藏它們

名字:周開顏
學號:2017141461386

經測試,所有功能成功實現
'''

import requests
from bs4 import BeautifulSoup

'''
用於登陸github的函式
傳入賬號密碼,登陸並返回登陸後的cookies
'''


def login(username, password):
    #get登陸頁面並獲取 authenticity_token 和 cookies(登陸需要)
    r1 = requests.get('https://github.com/login')
    soup = BeautifulSoup(r1.text, features='lxml')

    #獲取authenticity_token
    att = soup.find(name='input', attrs={
        'name': 'authenticity_token'}).get('value')
    #獲取cookies
    cks = r1.cookies.get_dict()

    #利用獲取的資訊登陸github
    r2 = requests.post(
        'https://github.com/session',
        data={
            'commit': 'Sign in',
            'utf8': '✓',
            'authenticity_token': att,
            'login': username,
            'password': password
        },
        cookies=cks
    )
    print("successed login!")
    return r2.cookies.get_dict()


'''
用於列印並返回前十個最受歡迎的庫
傳入的是搜尋的語言,這個程式需要傳入'python',
返回的是一個存有前十個庫的'作者名/庫名'的List
'''


def find_top10(language):
    #利用github提供的api介面進行搜尋
    response = requests.get(
        "https://api.github.com/search/repositories?q=language:%s&sort=stars" % (language))

    #檢測是否請求成功
    if(response.status_code != 200):
        print('error! in find_top10(): fail to request')
        return None

    #獲取的是一個json格式的字典物件
    j = response.json()
    #keyword 'items'下的包括了前三十個庫的所有詳細資訊
    progress = j['items']

    #儲存前十個資料
    message = []
    for i in range(10):
        pro = j['items'][i]
        message.append(pro['full_name'])
        #依次列印
        print('top%d:' % (i+1), pro['name'])
    return message


'''
利用登陸的cookies點選star收藏專案

這裡我分析了某個庫的網頁程式碼,按鈕'star'中,提供了一‘authenticity_token’和一個用於post的連結(https://github.com/作者名/庫名/star),只要獲取‘authenticity_token’並用登陸的cookies訪問連結,即可實現點選該按鈕的同樣效果。

所以只需要傳入cookies 和 作者名/庫名即可
'''


def get_stared(cookie, name):
    #get到該庫的介面並得到用於 點選star的post提交的authenticity_token
    get2 = requests.get(
        #利用傳入的‘作者名/庫名’進行操作
        'https://github.com/%s' % (name),
        cookies=cookie
    )
    cookie = get2.cookies.get_dict()
    #檢驗請求情況
    if(get2.status_code != 200):
        print('error! in get_stared(): get: fail to request')
        return None

    #得到authenticity_token
    soup2 = BeautifulSoup(get2.text, features='lxml')
    soup = soup2.find('form', {'class': 'unstarred js-social-form'})
    att2 = soup.find(name='input', attrs={
        'name': 'authenticity_token'}).get('value')

    #提交Post請求,請求之後即收藏了該庫
    r = requests.post(
        'https://github.com/%s/star' % (name),
        data={
            'utf8': '✓',
            'authenticity_token': att2,
            'context': 'repository'
        },
        cookies=cookie
    )
    #檢驗請求情況,這裡比較特殊,返回錯誤碼400的時候收藏成功
    if(r.status_code != 400):
        print('error! in get_stared(): post: fail to request')
        return None
    print(name, 'stared')


#主函式
if __name__ == '__main__':
    #登陸
    id = input('please input your github id\n')
    ps = input('please input your github password\n')
    coks = login(id, ps)

    #獲取前十個最受歡迎的python庫
    messages = find_top10('python')

    #為這十個庫點star(收藏)
    for m in messages:
        if(type(m) == str):
            get_stared(coks, m)