pip安裝pycrypto報錯:Microsoft Visual C++ 14.0 is required. 和 SSLError: HTTPSConnectionPool的解決辦法

今天本打算把【Python3爬蟲】網易雲音樂爬蟲 的代碼敲一遍, 可是在安裝pycrypto總是報錯,html

 

因爲我計算是win10, 而且也有vs2017python

python3環境下安裝pycrypto的一些問題
Python踩坑之路-Python-3.6 安裝pycrypto 2.6.1各類疑難雜症及解決方案
windows 下的python 安裝pycrypto
pip安裝pycrypto報錯:Microsoft Visual C++ 14.0 is required. 的解決辦法c++

而個人 解決 方式和pip安裝pycrypto報錯:Microsoft Visual C++ 14.0 is required. 的解決辦法 一致:git

1.首先安裝必要的C++的東西,github

 

 

先前也是選擇性的安裝一些 必要的插件, 搞了好久, 後來火了,直接安裝c++桌面開發json

2。設置VCINSTALLDIR環境變量, 好比VS2015 的設置爲:D:\Program Files (x86)\Microsoft Visual Studio 14.0\VC,可是我是vs2017就設置爲D:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\VC 竟然不對,後來搜索stdint.h文件才發現應是D:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\VC\Tools\MSVC\14.14.26428\windows

實際上我還設置了餓個環境變量 VS140COMNTOOLS = D:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\VC\Auxiliary\Build api

VS100COMNTOOLS=%VS140COMNTOOLS%dom

3. 從新打開CMD,鍵入set CL=/FI"%VCINSTALLDIR%\\INCLUDE\\stdint.h" 。再用pip安裝就能夠成功。函數

 

注:在實踐過程當中,發現pip有可能報 UnicodeDecodeError: 'utf-8' codec can't decode byte... 錯誤,這時須要將CMD的終端編碼用「CHCP 65001」命令改成「UTF-8」後再安裝。

在成功安裝以後,若是import的時候沒有Crypto而只有crypto,先打開Python安裝目錄下的Lib\site-packages\crypto文件夾,若是裏面有Cipher文件夾,就返回到Lib\site-packages目錄下把crypto重命名爲Crypto,而後應該就能夠成功導入了

因爲是請求https,因此有時候很容易遇到以下錯誤
requests.exceptions.SSLError: HTTPSConnectionPool(host='music.163.com', port=443):

解決辦法:代碼調用了urllib3.disable_warnings()函數,來確保不會發生警告。

import requests
from requests.packages import urllib3
urllib3.disable_warnings()
r = requests.get('https://www.12306.cn', verify=False)
print(r.status_code)

或者

import requests
import logging
logging.captureWarnings(True)
r = requests.get('https://www.12306.cn', verify=False)
print(r.status_code)

最後的python 代碼:

# 爬取保存指定歌曲的全部評論並生成詞雲
import jieba
import codecs
import base64
import requests
from math import floor, ceil
from random import random
from Crypto.Cipher import AES
from wordcloud import WordCloud
from multiprocessing import Pool
from requests.packages import urllib3


headers = {'Host': 'music.163.com',
           'Referer': 'http://music.163.com/',
           'Upgrade-Insecure-Requests': '1',
           'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
                         'Chrome/66.0.3359.181 Safari/537.36'
           }


# 爬取並保存評論內容
def get_comments(data):
    # data=[song_id,song_name,page_num]
    url = 'https://music.163.com/weapi/v1/resource/comments/R_SO_4_' + str(data[0]) + '?csrf_token='
    # 獲得兩個加密參數
    text, key = get_params(data[2])
    # 發送post請求
    urllib3.disable_warnings()
    res = requests.post(url, headers=headers, data={"params": text, "encSecKey": key}, verify=False)
    if res.status_code == 200:
        print("正在爬取第{}頁的評論".format(data[2]))
        # 解析
        comments = res.json()['comments']
        # 存儲
        with open(data[1] + '.txt', 'a', encoding="utf-8") as f:
            for i in comments:
                f.write(i['content'] + "\n")
    else:
        print("爬取失敗!")


# 生成詞雲
def make_cloud(txt_name):
    with open(txt_name + ".txt", 'r', encoding="utf-8") as f:
        txt = f.read()
    # 結巴分詞
    text = ''.join(jieba.cut(txt))
    # 定義一個詞雲
    wc = WordCloud(
        font_path="font.ttf",
        width=1200,
        height=800,
        max_words=100,
        max_font_size=200,
        min_font_size=10
    )
    # 生成詞雲
    wc.generate(text)
    # 保存爲圖片
    wc.to_file(txt_name + ".png")


# 生成隨機字符串
def generate_random_string(length):
    string = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
    # 初始化隨機字符串
    random_string = ""
    # 生成一個長度爲length的隨機字符串
    for i in range(length):
        random_string += string[int(floor(random() * len(string)))]
    return random_string


# AES加密
def aes_encrypt(msg, key):
    # 若是不是16的倍數則進行填充
    padding = 16 - len(msg) % 16
    # 這裏使用padding對應的單字符進行填充
    msg += padding * chr(padding)
    # 用來加密或者解密的初始向量(必須是16位)
    iv = '0102030405060708'
    # AES加密
    cipher = AES.new(key, AES.MODE_CBC, iv)
    # 加密後獲得的是bytes類型的數據
    encrypt_bytes = cipher.encrypt(msg)
    # 使用Base64進行編碼,返回byte字符串
    encode_string = base64.b64encode(encrypt_bytes)
    # 對byte字符串按utf-8進行解碼
    encrypt_text = encode_string.decode('utf-8')
    # 返回結果
    return encrypt_text


# RSA加密
def rsa_encrypt(random_string, key, f):
    # 隨機字符串逆序排列
    string = random_string[::-1]
    # 將隨機字符串轉換成byte類型數據
    text = bytes(string, 'utf-8')
    # RSA加密
    sec_key = int(codecs.encode(text, encoding='hex'), 16) ** int(key, 16) % int(f, 16)
    # 返回結果
    return format(sec_key, 'x').zfill(256)


# 獲取參數
def get_params(page):
    # 偏移量
    offset = (page - 1) * 20
    # offset和limit是必選參數,其餘參數是可選的
    msg = '{"offset":' + str(offset) + ',"total":"True","limit":"20","csrf_token":""}'
    key = '0CoJUm6Qyw8W8jud'
    f = '00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a87' \
        '6aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9' \
        'd05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b' \
        '8e289dc6935b3ece0462db0a22b8e7'
    e = '010001'
    # 生成長度爲16的隨機字符串
    i = generate_random_string(16)
    # 第一次AES加密
    enc_text = aes_encrypt(msg, key)
    # 第二次AES加密以後獲得params的值
    encText = aes_encrypt(enc_text, i)
    # RSA加密以後獲得encSecKey的值
    encSecKey = rsa_encrypt(i, e, f)
    return encText, encSecKey


def main():
    song_id = 108545
    song_name = "伯樂"
    # 構造url
    u = 'https://music.163.com/weapi/v1/resource/comments/R_SO_4_' + str(song_id) + '?csrf_token='
    # 構造參數
    t, k = get_params(1)
    # 構造data
    d = {'params': t, 'encSecKey': k}
    # 發送post請求並獲得結果
    urllib3.disable_warnings()
    r = requests.post(u, headers=headers, data=d, verify=False)
    # 提取評論總數(除開熱評)
    page_count = ceil((r.json()['total'] - 15) / 20)
    # 構造全部參數
    data_list = [(song_id, song_name, i + 1) for i in range(int(page_count))]
    # 構造進程池
    pool = Pool(processes=4)
    # 獲取評論
    print("開始爬取,請等待...")
    pool.map(get_comments, data_list)
    # 生成詞雲
    make_cloud(song_name)


if __name__ == "__main__":
    main()
font.ttf
相關文章
相關標籤/搜索