标签 Python 下的文章

在Python3.3以及版本之前我们创建虚拟环境的时候都是使用的virtualenv,平时使用起来也比较方便,不过最近小编发现virtualenv已经装不上了。原来在Python3.3以上的版本中可以使用venv模块原生支持虚拟环境,也就是说原生的venv模块可以代替Python之前的virtualenv
venv模块和之前的virtualenv创建的虚拟环境,都可以提供与系统Python的隔离。每一个虚拟环境都有其自己的Python二进制(允许有不同的Python版本创作环境),并且可以拥有自己独立的一套Python包,对于项目的管理十分方便。但是需要注意的是,在Python3.3中使用venv命令创建的环境不包含pip,你需要进行手动安装,不过呢在Python3.4中改进了这一个缺陷。

使用方法:
创建虚拟环境

python3 -m venv [虚拟环境的名字]

mac启动虚拟环境

source [虚拟环境的名字]/bin/activate

windows启动虚拟环境

[虚拟环境的名字]\Scripts\activate.bat

退出虚拟环境

deactivate

如果是直接使用pip install M2Crypto安装的话就会出现

SWIG/_m2crypto.i:62: Error: Unable to find 'openssl/opensslv.h'
  SWIG/_m2crypto.i:68: Error: Unable to find 'openssl/safestack.h'
  SWIG/_evp.i:12: Error: Unable to find 'openssl/opensslconf.h'
  SWIG/_rc4.i:5: Error: Unable to find 'openssl/opensslconf.h'
  SWIG/_ec.i:7: Error: Unable to find 'openssl/opensslconf.h'
  error: command 'swig' failed with exit status 1
  ----------------------------------------
  ERROR: Failed building wheel for m2crypto

这样的错误(没写完整哈),这是由于M2Crypto有两个依赖,openssl和swig,在Mac上需要首先安装这两个包,才能安装M2Crypto。
我们可以通过brew来安装这两个包,如果你的电脑没有brew的话,你就得先安装brew,小编在[post cid="773" /]这篇文章中介绍过怎么安装。下面我们来安装openssl和swig。

brew install openssl
brew install swig
# 有时候需要手动链接swig
# brew unlink swig && brew link swig

这时候就可以安装M2Crypto,不过还是有时候会报错,我们需要指定下地址

env LDFLAGS="-L$(brew --prefix openssl)/lib" CFLAGS="-I$(brew --prefix openssl)/include" SWIG_FEATURES="-cpperraswarn -includeall -I$(brew --prefix openssl)/include"

然后我们就可以安装了M2Crypto

pip install M2Crypto

做过爬虫的小伙伴应该都很清楚要伪装自己的请求,包括请求头等,同时也要隐藏自己的ip,不然的话很快自己的ip就被封了,访问不了了。免费的代理ip很多,也有收费的,要是你的资金允许,或者对ip要求比较高的话,建议直接去购买收费的代理ip,直接通过接口就能获取。小编在这里主要是说下爬取的快代理的免费ip的部分,并且验证他对自己要访问的网站是否可以访问,并且保存到redis或者文件当中。
我们打开快代理的网站,免费代理的页面https://www.kuaidaili.com/free/inha/1/
好了,下面下面分享下爬取的代码吧

import requests
from lxml import etree
from fake_useragent import UserAgent
import redis
import threading
import time


pool = redis.ConnectionPool(host='127.0.0.1', port=6379, db=1, password='')

# 测试的URL
test_url = "https://www.1688.com/"

def get_proxy(url):
    '''爬取快代理的免费代理ip'''
    headers= {'User-Agent':str(UserAgent(verify_ssl=False).random)}
    response = requests.get(url,headers=headers)
    selector = etree.HTML(response.text)
    proxies = []
    for each in selector.xpath('//table[@class="table table-bordered table-striped"]/tbody/tr')[1:]:
        ip = each.xpath("./td[1]/text()")[0]
        port = each.xpath("./td[2]/text()")[0]
        proxy = ip + ":" + port
        proxies.append(proxy)
    test_proxies(proxies, test_url, 'ip_proxy')

def test_proxies(proxies, test_url , ipname):
    '''检查IP是否可以使用'''
    proxies = proxies
    normal_proxies = []
    count = 1
    for proxy in proxies:
        print("第{}个, {}".format(count, proxy))
        count += 1
        try:
            headers= {'User-Agent':str(UserAgent(verify_ssl=False).random)}
            response = requests.get(test_url, headers=headers, proxies={"http": proxy}, timeout=1)
            time = response.elapsed.total_seconds()
            if response.status_code == 200:
                print("{}可以使用".format(proxy))
                normal_proxies.append(proxy)
            else:
                print("{}--{}--可以不可以访问".format(proxy, response.status_code))
        except Exception as e:
            print("{}无效".format(proxy))
    write_proxy(normal_proxies, ipname)

def write_proxy(proxies, name):
    '''写入文件或redis'''
    for proxy in proxies:
        # 写入redis
        r = redis.Redis(connection_pool=pool)
        r.lpush(name, proxy)
        print(r.lrange(name, 0, -1))
        # 写入文件
        with open("./{}.txt".format(name), 'a+') as f:
            f.write(proxy + '\n')
    print("录入完成!!!")

if __name__ == "__main__":
    base_url = "https://www.kuaidaili.com/free/inha/{}/"
    for i in range(1, 3000):
        print("第{}页".format(i))
        url = base_url.format(i)
        get_proxy(url)

5.jpg

User-Agent 就是用户代理,又叫报头,是一串字符串,相当于浏览器的身份证号,我们在利用python发送请求的时候,默认为: python-requests/2.22.0,所以我们在利用爬虫爬取网站数据时,频繁更换它可以避免触发相应的反爬机制。为了解决这个问题,我们引入了fake-useragent,fake-useragent对频繁更换User-Agent提供了很好的支持,可谓防反扒利器。下面我们就介绍fake-useragent。
安装

pip install fake-useragent

使用

from fake_useragent import UserAgent
headers= {'User-Agent':str(UserAgent().random)}
r = requests.get(url, proxies=proxies, headers=headers, timeout=10)

fake-useragent Maximum amount of retries reached 错误的解决方法

添加参数verify_ssl=False也就是:UserAgent(verify_ssl=False).random

在Python中,我们使用json.dumps()将 Python 对象编码成 JSON 字符串的时候,我们发现会出现很多空格,这个在json.dumps()官方文档里也说明了,为了美观默认会加上逗号空格和冒号空格。因为有时候我们需要处理字符串,比如加密等,但是由于多了空格,加密后肯定不一致的,那么我们需要去掉这些空格,按照文档里说的,我们只需要加上separators=(',',':')这个参数就可以解决了。
示例代码

import json
ll = ["123, "1234"]
json.dumps(ll, separators=(',', ':'))

我们可以利用python的PyPinyin库来获取汉字的拼音,我们先来写一个简单的案例

import pypinyin
print(pypinyin.pinyin( "小宁博客"))

# [['xiǎo'], ['níng'], ['bó'], ['kè']]

是不是很简单呢,我们只用了两行代码就实现了最基础的汉字转拼音。要是多音字怎么办呢?
这里PyPinyin也给我们做了处理了

from pypinyin import pinyin, lazy_pinyin, Style
x = "我画了一个长方形"
# 按照意思自动标识声调
print(pinyin(x)) # [['wǒ'], ['huà'], ['le'], ['yí'], ['gè'], ['cháng'], ['fāng'], ['xíng']]
# 列举出所有的声调
print(pinyin(x, heteronym=True)) # [['wǒ'], ['huà'], ['le', 'liǎo', 'liào'], ['yí'], ['gè'], ['cháng'], ['fāng'], ['xíng']]
# 忽略声调
print(lazy_pinyin(x)) #['wo', 'hua', 'le', 'yi', 'ge', 'chang', 'fang', 'xing']

我们来详细分析下这个函数pypinyin.pinyin(hans, style=<Style.TONE: 1>, heteronym=False, errors='default', strict=True)

  • 参数

    • hans汉字字符串。
    • style指定拼音风格,默认是 TONE风格。
    • errors指定如何处理没有拼音的字符。
    • heteronym指定是否启用多音字。
    • strict指定是否严格遵照《汉语拼音方案》来处理声母和韵母。

我们再来看下pypinyin.lazy_pinyin(hans, style=<Style.NORMAL: 0>, errors='default', strict=True)

  • 参数

    • hans汉字字符串。
    • style指定拼音风格,默认是 TONE风格。
    • errors指定如何处理没有拼音的字符。
    • strict指定是否严格遵照《汉语拼音方案》来处理声母和韵母。

自定义拼音库
自定义拼音库--载入用户自定义的单字拼音库`pypinyin.load_single_dict(pinyin_dict, style='default')

  • 参数

    • pinyin_dict (dict)单字拼音库。比如: {0x963F: u"ā,ē"}
    • stylepinyin_dict 参数值的拼音库风格. 支持 ‘default’, ‘tone2’

自定义拼音库--载入用户自定义的词语拼音库pypinyin.load_phrases_dict(phrases_dict, style='default')

  • 参数

    • phrases_dict (dict)词语拼音库。比如: {u"阿爸": [[u"ā"], [u"bà"]]}
    • style phrases_dict参数值的拼音库风格. 支持 ‘default’, ‘tone2’

附:风格列表

  • NORMAL = 0普通风格,不带声调。如: 中国 -> zhong guo。
  • TONE = 1标准声调风格,拼音声调在韵母第一个字母上(默认风格)。如: 中国 -> zhōng guó。
  • TONE2 = 2声调风格2,即拼音声调在各个韵母之后,用数字 [1-4] 进行表示。如: 中国 -> zho1ng guo2。
  • TONE3 = 8声调风格3,即拼音声调在各个拼音之后,用数字 [1-4] 进行表示。如: 中国 -> zhong1 guo2。
  • INITIALS = 3声母风格,只返回各个拼音的声母部分(注:有的拼音没有声母,详见 #27_)。如: 中国 -> zh g。
  • FIRST_LETTER = 4首字母风格,只返回拼音的首字母部分。如: 中国 -> z g。
  • FINALS = 5韵母风格,只返回各个拼音的韵母部分,不带声调。如: 中国 -> ong uo。
  • FINALS_TONE = 6标准韵母风格,带声调,声调在韵母第一个字母上。如:中国 -> ōng uó。
  • FINALS_TONE2 = 7韵母风格2,带声调,声调在各个韵母之后,用数字 [1-4] 进行表示。如: 中国 -> o1ng uo2。
  • FINALS_TONE3 = 9韵母风格3,带声调,声调在各个拼音之后,用数字 [1-4] 进行表示。如: 中国 -> ong1 uo2。
  • BOPOMOFO = 10注音风格,带声调,阴平(第一声)不标。如: 中国 -> ㄓㄨㄥ ㄍㄨㄛˊ。
  • BOPOMOFO_FIRST = 11注音风格,仅首字母。如: 中国 -> ㄓ ㄍ。
  • CYRILLIC = 12汉语拼音与俄语字母对照风格,声调在各个拼音之后,用数字 [1-4] 进行表示。如: 中国 -> чжун1 го2。
  • CYRILLIC_FIRST = 13汉语拼音与俄语字母对照风格,仅首字母。如: 中国 -> ч г。

python使用jieba库进行中文分词,我们可以吧一篇中文文章里面的词语提取出来进行分析,这时候我们可以采用jieba库,python2和python3都支持,目前jieba库支持3种分词模式:精确模式、全模式、搜索引擎模式,并且支持繁体分词,还支持自定义词典。

使用之前我们要先安装jieba库

pip install jieba

然后导入jieba库

import jieba
import jieba.posseg as pseg #词性标注
import jieba.analyse as anls #关键词提取

分词

我们首先看下精确模式、全模式、搜索引擎模式的输出情况,默认是精确模式。

  • jieba.cut 方法接受两个输入参数: 第一个参数为需要分词的字符串,cut_all参数用来控制是否采用全模式,默认是精确模式。
  • jieba.cut_for_search方法接受一个参数:需要分词的字符串,该方法适合用于搜索引擎构建倒排索引的分词,粒度比较细。

jieba.cut以及jieba.cut_for_search返回的结构都是一个可迭代的generator,可以使用for循环来获得分词后得到的每一个词语(unicode),也可以用list(jieba.cut(...))转化为list

# 全模式
seg_list = jieba.cut("我要进行关键词提取", cut_all=True)
print("【全模式】:" + "/ ".join(seg_list)) 

# 精确模式
seg_list = jieba.cut("我要进行关键词提取", cut_all=False)
print("【精确模式】:" + "/ ".join(seg_list)) 


#【全模式】:我/ 要/ 进行/ 关键/ 关键词/ 提取
#【精确模式】:我要/ 进行/ 关键词/ 提取
#【搜索引擎模式】:我要/ 进行/ 关键/ 关键词/ 提取

精确模式,返回的是一个生成器,这对大数据量数据的分词十分重要。
全模式,可见全模式就是把文本分成尽可能多的词。

获取词性

我们还可以通过jiaba这个库把词性进行区分,比如动词,名词等

import jieba.posseg as psg

seg_list = psg.cut("我要进行关键词提取")
print([(s.word, s.flag) for s in seg_list])
# [('我', 'r'), ('要', 'v'), ('进行', 'v'), ('关键词', 'n'), ('提取', 'v')]

我们还可以提取动词或者名词,我们来提取下里面的动词

import jieba.posseg as psg

seg_list = psg.cut("我要进行关键词提取")
print([(s.word, s.flag) for s in seg_list if s.flag.startswith('v')])

获取出现次数最多的词语

from collections import Counter
c = Counter("我要进行关键词提取,我要进行学习,好好学习,天天向上。").most_common(3)
print(c)

添加字典增加准确性

我们可以指定自己自定义的词典,以便包含jieba词库里没有的词。虽然jieba有新词识别能力,但是自行添加新词可以保证更高的正确率。
用法: jieba.load_userdict(file_name) # file_name为自定义词典的路径

并行分词

在文本数据量非常大的时候,为了提高分词效率,开启并行分词就很有必要了。jieba支持并行分词,基于python自带的multiprocessing模块,但要注意的是在Windows环境貌似不支持。
用法:
开启并行分词模式,参数为并发执行的进程数 jieba.enable_parallel(5)
关闭并行分词模式 jieba.disable_parallel()

Python使用QRCode生成二维码,qrcode会依赖Image这个包,所以我们首先安装qrcode和Image:

pip install qrcode
pip install Image
  • 首先我们来写一个最简单的案例,生成一个内容为hello sunxiaoning的二维码,​保存到本地,执行以下脚本,就可以生成一个hello.png的文件,并且自动打开。我们扫描之后就可以看到二维码里面的内容了。是不是很简单啊,​人生苦短,我用python。

    import qrcode 
    img = qrcode.make('hello sunxiaoning')
    # 保存二维码
    img.save('hello.png')
    # 展示二维码
    img.show()
  • 我们在来设置一个中间带有头像的二维码,我们要先安装下Pillow。使用pip install Pillow即可。

    import qrcode
    from PIL import Image
    qr = qrcode.QRCode(
            version=1,
            error_correction=qrcode.constants.ERROR_CORRECT_H,
            box_size=5,
            border=4,
        )
    
    # 添加数据
    qr.add_data('Hello sunxiaoning')
    # 填充数据
    qr.make(fit=True)
    # 生成图片
    img = qr.make_image(fill_color="orange", back_color="white")
    
    # 添加头像,打开头像照片
    icon = Image.open("1.jpeg")
    # 获取图片的宽高
    img_w, img_h = img.size
    # 参数设置头像的大小
    factor = 6
    size_w = int(img_w / factor)
    size_h = int(img_h / factor)
    icon_w, icon_h = icon.size
    if icon_w > size_w:
        icon_w = size_w
    if icon_h > size_h:
        icon_h = size_h
    # 设置头像的尺寸
    icon = icon.resize((icon_w, icon_h), Image.ANTIALIAS)
    
    w = int((img_w - icon_w) / 2)
    h = int((img_h - icon_h) / 2)
    # 粘贴头像
    img.paste(icon, (w, h), mask=None)
    # 保存img
    img.save('hello.png')
    # 展示二维码
    img.show()

参数详解

  • version 控制二维码的大小,取值范围从1到40。取最小值1时,二维码大小为21*21。取值为 None (默认)或者使用fit=true参数(默认)时,二维码会自动调整大小。
  • error_correction控制二维码纠错级别。

    • ERRORCORRECTL大约7%或者更少的错误会被更正。
    • ERRORCORRECTM默认值,大约15%或者更少的错误会被更正。
    • ERRORCORRECTQ大约25%或者更少的错误会被更正。
    • ERRORCORRECTH大约30%或者更少的错误会被更正。
  • box_size控制二维码中每个格子的像素数,默认为 10。
  • border控制二维码四周留白包含的格子数,默认为 4。
  • image_factory选择生成图片的形式,默认为 PIL 图像。
  • mask_pattern选择生成图片的的掩模。

方法详解

  • add_data(str,optimize=20) 添加要转换的文字到data参数;如果使用了optimize优化参数,数据将被拆分为多个块来进行优化,以找到一个长度至少为这个值的足够简洁的方式来生成二维码。设置为“0”以避免优化。
  • make(fit=True)当fit参数为真或者没有给出version参数时,将会调用bestfit方法来找到适合数据的最小尺寸。如果没有设置maskpattern,将会调用bestmaskpattern方法来找到找到最有效的掩模图案。最后将这些数据传递给makeImpl方法来生成二维码。与qrcode本体的make方法不一样的是,这个方法没有任何返回值。
  • makeimage(fillcolor=None, backcolor=None,imagefactory=None):创建二维码的图像并返回,默认为 PIL 图像。可以在这里设置二维码的颜色。
  • clear 清空所有数据。
  • get_matrix 返回二维码数组。
  • print_ascii(out=None, tty=False, invert=False)可以用字符画的形式来输出二维码,但是需要注意的是扫的时候不一定可以扫出来,谨慎使用。

今天小编给大家介绍一个有趣的事情,让代码开口说话,简单点说就是python利用pyttsx3实现文字转语音。感觉还是蛮有趣的,并且支持中文哦。

  • 首先我们先安装pyttsx3

    pip install pyttsx3
  • 如果是windows操作系统,并且未安装pywin32, 需要安装pywin32

    pip install pywin32
  • 我们首先让代码说句Hello World,然后再说句中文

    import pyttsx3 
     
    # 模块初始化
    engine = pyttsx3.init() 
    print('准备开始语音播报...')
    engine.say('Hello World')
    engine.say('孙肖宁')
    # 等待语音播报完毕, 不写这个是不可以的哦
    engine.runAndWait()

    是不是很简单呢

  • 我们还可以进行语速控制、音量控制、更换发音人声音

    import pyttsx3
    
    # 模块初始化
    engine = pyttsx3.init()
    print('准备开始语音播报...')
    
    # 语速控制,默认值为200
    rate = engine.getProperty('rate')
    engine.setProperty('rate', rate - 50)
    # 音量控制,范围为0.0-1.0
    volume = engine.getProperty('volume')
    engine.setProperty('volume', 0.6)
    # 添加朗读文本
    engine.say('窗前明月光,疑是地上霜。')
    
    # 等待语音播报完毕
    engine.runAndWait()
  • 我们再来说下更换发音人的声音,目前中文仅支持3种

    • 普通话: com.apple.speech.synthesis.voice.ting-ting.premium
    • 粤语 :com.apple.speech.synthesis.voice.ting-ting.premium
    • 台湾女生普通话: com.apple.speech.synthesis.voice.mei-jia

      import pyttsx3
      
      # 模块初始化
      engine = pyttsx3.init()
      volume = engine.getProperty('volume')
      
      # 普通话发音
      voices = engine.setProperty(
      'voice', "com.apple.speech.synthesis.voice.ting-ting.premium")
      
      # 标准的粤语发音
      # voices = engine.setProperty(
      #       'voice', "com.apple.speech.synthesis.voice.sin-ji")
      
      # 台湾女生普通话发音
      # voices = engine.setProperty(  
      #     'voice', "com.apple.speech.synthesis.voice.mei-jia")
      print('准备开始语音播报...')
      # 输入语音播报词语
      engine.setProperty('volume', 3)
      engine.say("窗前明月光,疑是地上霜。举头望明月,低头思故乡。")
      
      engine.runAndWait()
      engine.stop()
      另外你可以尝试查看内置的其他声音,遍历下面的voices即可
      voices = engine.getProperty('voices')
      engine.setProperty('voice', voices[0].id)

python利用pyttsx3实现文字转语音   .jpg
详解

  • 语音引擎工厂类似于设计模式中的“工厂模式”,pyttsx3通过初始化来获取语音引擎。当我们第一次调用init操作的时候,会返回一个pyttsx3的engine对象,再次调用的时候,如果存在engine对象实例,就会使用现有的,否则再重新创建一个。
    pyttsx.init([driverName : string, debug : bool]) → pyttsx.Engine
    从方法声明上来看,第一个参数指定的是语音驱动的名称,这个在底层适合操作系统密切相关的。如下:

    • drivename:由pyttsx3.driver模块根据操作系统类型来调用,默认使用当前操作系统可以使用的最好的驱动。

      • sapi5 - SAPI5 on Windows
      • nsss - NSSpeechSynthesizer on Mac OS X
      • espeak - eSpeak on every other platform
    • debug: 要不要以调试状态输出,开发阶段可以设置为True。

函数说明

  • connect()在给定的topic上添加回调通知

    • 参数:

      • topic(string):要描述的事件名称;
      • cb(callable):回调函数。
    • 返回值: dict
  • disconnect()结束连接

    • 参数:

      • token(dict):回调失联的返回标记
    • 返回值: Void
  • endLoop()简单来说就是结束事件循环
  • getProperty()获取当前引擎实例的属性值

    • 参数:

      • name(string):rate: 每分钟字数的语音速率,默认为每分钟200个。
      • name(string):voice: 语音的字符串标识符。
      • name(string):voices: pyttsx3.voice.Voice描述符对象列表。
      • name(string):volume:音量的大小。
    • 返回值: Object
  • setProperty()获取当前引擎实例的属性值

    • 参数:

      • name(string):rate: 每分钟字数的语音速率,默认为每分钟200个。
      • name(string):voice: 语音的字符串标识符。
      • name(string):volume:音量的大小。
      • value(int):rate: 设置每分钟读的字数。
      • value:voice:设置发音,后文中会再讲到。
      • valu(float):volume:设置音量大小,0.0-1.0之间;默认1.0。
    • 返回值: Object
  • say()预设要朗读的文本数据

    • 参数:

      • text(unicode):要进行朗读的文本数据。
      • name(strin):关联发音人(一般用不到)
  • runAndWait()当事件队列中事件全部清空的时候返回
  • startLoop()开启事件队列

    • 参数:

      • [useDriverLoop(bool)]:是否启用驱动循环。
  • stop()停止当前讲话并清除命令队列。