import requestsdef search_github_repositories ( keyword, token= None , language= None , max_results= 1000 ) : """通過 GitHub API 搜索倉庫,支持分頁獲取所有結果(最多 1000 條):param keyword: 搜索關鍵詞:param token: GitHub Token(可選,但建議使用以提高速率限制):param language: 過濾語言:param max_results: 最大結果數(GitHub 允許最多 1000 條):return: 倉庫列表""" url = "https://api.github.com/search/repositories" headers = { "Accept" : "application/vnd.github.v3+json" } if token: headers[ "Authorization" ] = f"Bearer { token} " query = keywordif language: query += f" language: { language} " repositories = [ ] page = 1 per_page = 100 while len ( repositories) < max_results: params = { "q" : query, "sort" : "stars" , "order" : "desc" , "page" : page, "per_page" : per_page} try : response = requests. get( url, headers= headers, params= params) response. raise_for_status( ) data = response. json( ) if not data. get( "items" ) : break for item in data[ "items" ] : repo_info = { "name" : item[ "name" ] , "owner" : item[ "owner" ] [ "login" ] , "url" : item[ "html_url" ] , "clone_url" : item[ "clone_url" ] , "description" : item[ "description" ] , "language" : item[ "language" ] , "stars" : item[ "stargazers_count" ] } repositories. append( repo_info) if len ( repositories) >= max_results: break page += 1 if page > 10 : break except requests. exceptions. RequestException as e: print ( f"請求失敗: { e} " ) break return repositoriesdef save_to_txt ( results, filename= "github_results.txt" ) : """將結果保存到文本文件:param results: 倉庫列表:param filename: 保存文件名""" with open ( filename, "w" , encoding= "utf-8" ) as f: for repo in results: line = ( f"倉庫: { repo[ 'owner' ] } / { repo[ 'name' ] } | " f"URL: { repo[ 'url' ] } | " f"語言: { repo[ 'language' ] } | " f"星數: { repo[ 'stars' ] } | " f"克隆地址: { repo[ 'clone_url' ] } \n" ) f. write( line) print ( f"結果已保存至 { filename} " )
if __name__ == "__main__" : keyword = "Aerospace Control" language = "Python" token = "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" results = search_github_repositories( keyword, token, language= language, max_results= 1000 ) if results: print ( f"找到 { len ( results) } 個 { language} 相關倉庫:" ) for idx, repo in enumerate ( results, 1 ) : print ( f"\n { idx} . { repo[ 'owner' ] } / { repo[ 'name' ] } " ) print ( f" URL: { repo[ 'url' ] } " ) print ( f" 語言: { repo[ 'language' ] } " ) print ( f" 克隆地址: { repo[ 'clone_url' ] } " ) else : print ( "未找到結果" ) if results: save_to_txt( results) print ( f"實際獲取 { len ( results) } 條結果" ) else : print ( "未找到結果" )