首页 文章 精选 留言 我的

精选列表

搜索[基础搭建],共10000篇文章
优秀的个人博客,低调大师

6、web爬虫讲解2—urllib库爬虫—基础使用—超时设置—自动模拟http请求

利用python系统自带的urllib库写简单爬虫 urlopen()获取一个URL的html源码read()读出html源码内容decode("utf-8")将字节转化成字符串 #!/usr/bin/env python # -*- coding:utf-8 -*- import urllib.request html = urllib.request.urlopen('http://edu.51cto.com/course/8360.html').read().decode("utf-8") print(html) <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="csrf-param" content="_csrf"> <meta name="csrf-token" content="X1pZZnpKWnQAIGkLFisPFT4jLlJNIWMHHWM6HBBnbiwPbz4/LH1pWQ=="> 正则获取页面指定内容 #!/usr/bin/env python # -*- coding:utf-8 -*- import urllib.request import re html = urllib.request.urlopen('http://edu.51cto.com/course/8360.html').read().decode("utf-8") #获取html源码 pat = "51CTO学院Python实战群\((\d*?)\)" #正则规则,获取到QQ号 rst = re.compile(pat).findall(html) print(rst) #['325935753'] urlretrieve()将网络文件下载保存到本地,参数1网络文件URL,参数2保存路径 #!/usr/bin/env python # -*- coding:utf-8 -*- from urllib import request import re import os file_path = os.path.join(os.getcwd() + '/222.html') #拼接文件保存路径 # print(file_path) request.urlretrieve('http://edu.51cto.com/course/8360.html', file_path) #下载这个文件保存到指定路径 urlcleanup()清除爬虫产生的内存 #!/usr/bin/env python # -*- coding:utf-8 -*- from urllib import request import re import os file_path = os.path.join(os.getcwd() + '/222.html') #拼接文件保存路径 # print(file_path) request.urlretrieve('http://edu.51cto.com/course/8360.html', file_path) #下载这个文件保存到指定路径 request.urlcleanup() info()查看抓取页面的简介 #!/usr/bin/env python # -*- coding:utf-8 -*- import urllib.request import re html = urllib.request.urlopen('http://edu.51cto.com/course/8360.html') #获取html源码 a = html.info() print(a) # C:\Users\admin\AppData\Local\Programs\Python\Python35\python.exe H:/py/15/chshi.py # Date: Tue, 25 Jul 2017 16:08:17 GMT # Content-Type: text/html; charset=UTF-8 # Transfer-Encoding: chunked # Connection: close # Set-Cookie: aliyungf_tc=AQAAALB8CzAikwwA9aReq63oa31pNIez; Path=/; HttpOnly # Server: Tengine # Vary: Accept-Encoding # Vary: Accept-Encoding # Vary: Accept-Encoding getcode()获取状态码 #!/usr/bin/env python # -*- coding:utf-8 -*- import urllib.request import re html = urllib.request.urlopen('http://edu.51cto.com/course/8360.html') #获取html源码 a = html.getcode() #获取状态码 print(a) #200 geturl()获取当前抓取页面的URL #!/usr/bin/env python # -*- coding:utf-8 -*- import urllib.request import re html = urllib.request.urlopen('http://edu.51cto.com/course/8360.html') #获取html源码 a = html.geturl() #获取当前抓取页面的URL print(a) #http://edu.51cto.com/course/8360.html timeout抓取超时设置,单位为秒 是指抓取一个页面时对方服务器响应太慢,或者很久没响应,设置一个超时时间,超过超时时间就不抓取了 #!/usr/bin/env python # -*- coding:utf-8 -*- import urllib.request import re html = urllib.request.urlopen('http://edu.51cto.com/course/8360.html',timeout=30) #获取html源码 a = html.geturl() #获取当前抓取页面的URL print(a) #http://edu.51cto.com/course/8360.html 自动模拟http请求 http请求一般常用的就是get请求和post请求 get请求 比如360搜索,就是通过get请求并且将用户的搜索关键词传入到服务器获取数据的 所以我们可以模拟百度http请求,构造关键词自动请求 quote()将关键词转码成浏览器认识的字符,默认网站不能是中文 #!/usr/bin/env python # -*- coding: utf-8 -*- import urllib.request import re gjc = "手机" #设置关键词 gjc = urllib.request.quote(gjc) #将关键词转码成浏览器认识的字符,默认网站不能是中文 url = "https://www.so.com/s?q="+gjc #构造url地址 # print(url) html = urllib.request.urlopen(url).read().decode("utf-8") #获取html源码 pat = "(\w*<em>\w*</em>\w*)" #正则获取相关标题 rst = re.compile(pat).findall(html) # print(rst) for i in rst: print(i) #循环出获取的标题 # 官网 < em > 手机 < / em > # 官网 < em > 手机 < / em > # 官网 < em > 手机 < / em > 这么低的价格 # 大牌 < em > 手机 < / em > 低价抢 # < em > 手机 < / em > # 淘宝网推荐 < em > 手机 < / em > # < em > 手机 < / em > # < em > 手机 < / em > # < em > 手机 < / em > # < em > 手机 < / em > # 苏宁易购买 < em > 手机 < / em > # 买 < em > 手机 < / em > # 买 < em > 手机 < / em > post请求 urlencode()封装post请求提交的表单数据,参数是字典形式的键值对表单数据Request()提交post请求,参数1是url地址,参数2是封装的表单数据 #!/usr/bin/env python # -*- coding: utf-8 -*- import urllib.request import urllib.parse posturl = "http://www.iqianyue.com/mypost/" shuju = urllib.parse.urlencode({ #urlencode()封装post请求提交的表单数据,参数是字典形式的键值对表单数据 'name': '123', 'pass': '456' }).encode('utf-8') req = urllib.request.Request(posturl,shuju) #Request()提交post请求,参数1是url地址,参数2是封装的表单数据 html = urllib.request.urlopen(req).read().decode("utf-8") #获取post请求返回的页面 print(html) 【转载自:http://www.lqkweb.com】

优秀的个人博客,低调大师

语音识别(ASR)基础介绍第二篇——万金油特征MFCC

上一章提到了整个发声与拾音及存储的原理。但是在了解ASR的过程中,发现基本上遇到的资料都避不开MFCC特征。 整个ASR的处理流程大致可以分为下图: 左侧是经典的处理流程,右侧是近期流行的流程。发生的变化是,将语言模型以下的部分变成端到端的了。 我们将语言模型以下的部分统一看成是声学模型就好。 而MFCC主要用在左侧的处理流程中,即“特征处理”的输出结果。 虽然可以看成,端到端的声学模型出来后,我们已经不需要MFCC了,直接输入音频即可。 不过这并不意味着MFCC就没用了。 在“根据发音确认发音人身份”等许多领域,MFCC还是个很短平快切粗暴有效的特征。 由于MFCC的重要性,和asr相关专业的人士交流时,最好是能提前具备此共识。 MFCC 细节介绍: MFCC给人的感觉像是孟德尔遗传定律。在人们还并不确定人耳是如何解析声音的时候,假设了这是一个傅里叶变换后的频域处理过程。然后,最近的医学研究成果表明,人耳也确实大致是这么工作的,对应的器官名字叫耳蜗,或蜗牛。 MFCC虽然名字就4个字母,但其实是集成了很多很多的思考和假设在里面。 了解过之后,你就不会再后悔大学数学的卷积操作毛用都没有了。 可谓是人类智慧的一大结晶。 一:整体流程 MFCC整体流程看其来好像有些复杂,但其实拆细了之后,会发现这个很符合常识的。 上图便是MFCC的主要流程。这里稍微提到一点,Cepstral 是 spectral的字母倒序,后者是频谱的意思,前者是倒谱的意思,就是把频谱倒回来。。。 这个定义确实有些冷。 图中的DFT和IDFT便是堪称深刻影响到了人类技术进程的经典技术——离散傅里叶变换及离散傅里叶逆变换。 这里就当成是傅里叶正逆变换就好。离散主要是因为处理的数据是离散的一个个数值,而不是坐标轴上那种可以无限往下细分的点。 整个处理流程从左上角开始看。 输入是第一章讲到的pcm文件,可以理解成一个数组,数值的大小表示声音的强弱。 至于频率等信息,是固定值,设定一下就好。 1、pre-emphasis 这个加强里掺杂着各种各样的“窗”or过滤器之类字眼的术语,其实原理挺简单的,那些个“窗”主要是信号处理领域的术语,大意就是对部分频率段的数据增强幅度。由于是已知的频率操作,可以根据公式事前转换为时域的操作(就是直接对pcm数据的操作) 2、滑动窗口 这里要交代的一个背景信息是,傅里叶变换针对的是一个时间片段的值,或者说,是一个数组,而非一个数组中的某个值。所以在提取特征的时候,首先要假设基本的发音单元所占用的时间,然后把这个时间片段的数据拿过来,做傅里叶变换。 但是怎么知道某段声音是从什么时候开始的呢? ——就是不知道的,这里采用滑动窗口就好了,差个1、2ms不影响分析的。 整个提取流程,起初是使用了滑动窗口,术语上管这个窗口叫frame。 一个frame的长度一般在20-25ms,然后窗口的移动步长在10ms左右。这也是上图最左侧所展示的内容。 这里的假设是,声音的最基本发音单元,至少需要20ms左右的发音时长。 得到关于frame的数组之后,接下来要为每个数组做一下离散傅里叶变换。 示意过程如下图: 这一步操作的依据或者说灵感主要来自上图左上角,就是大家发现,提取了一个个frame后,做下DFT,然后把各个frame对应的DFT数据放到一块(左上图中,纵轴是频域的横坐标-评率,频率,横轴是时间,每个横坐标上的点对应着一个frame,颜色的深浅代表对应频率下的幅度。傅里叶变化的本质就是拿一堆的正弦函数求和去拟合原始数据。这些sin cosin 函数,区别只在于 周期和幅度)。 把这些DFT之后的frame放到一块之后,就能明显的发现:音节在频域上确实有些区分度的。 左上图的蓝线表示那一段时间内,都是某个频率下的幅度特别大,这个给了个术语,叫做——共振峰。左上图的红线用来区分音节的边界。 有了灵感之后,滑动窗口+DFT(或者FFT 表示傅里叶变化)之后,输出就类似上图右边的效果—— 把一个关于frame的数组,转换成了关于这个frame的傅里叶变换后结果的数组。数组中,每个元素表示这个频率值下的幅度。 3、梅尔滤波 工序2已经把数据变成了关于frameDFT之后的数组。既然已经都变成了频域后的数据,接下来要做的,很直观的——就是把人耳敏感的频率下的数据加强,人耳不敏感的频率下的数据减弱。充分的模拟人耳。 梅尔发现,人耳对各个频域段的声音的敏感程度不同,对高频的敏感度较低,所以,梅尔就做了映射方法, 低频区给与较多的区分度,高频区给与较少的数据表示。所以,他的工作可以理解是定义了一个map或者说函数, 如上图右上角。这函数的横轴和前面的DFT结果的长度一一对应,然后对每个DFT的结果中的每个元素,乘以对应纵轴上的数值。输出的结果如上图右下角。说白了,就是每次拿右上角图中的一部分乘以DFT之后的数据,得到一个值。 最终把DFT变成一系列Y的数组。 4、提取声道信息/倒谱 上图左展示的是人的发声过程——气体从胸腔发出(基音),经过声道和口腔的改造,最终形成声音。 而气体经过声道改造的过程,恰恰就是数学中的卷积运算过程。 这里特别像软件开发中归纳的思想,卷积是一个抽象出来的操作。很多基信号+加工信号构成新信号的操作基本都适用。 前面讲到,根据共振峰的位置,大致就能区分出音节or音素出来。而共振峰主要是Filter or 声道及口腔带来的信息。所以根据抓主干的哲学指导,想让特征更鲜明,需要提取Filter部分的信息。 既然Filter与基音是卷积操作,那么接下来就是一系列的数学推导骚操作,这里面依据了一个公式,那就是:时域的卷积 = 频域的乘积。 而乘积运算左右加log就变成了加法运算。然后就得到了如上图右下角的效果。然后就发现,取了log后,再对信号做一下傅里叶变换,就能得到右下图中左侧的效果,感觉在新的频域里把属于基音的频率去掉就好了。 这样一下子就简单了。就是取了log后再搞一次傅里叶变换。 但这里实际操作时,由于我们原来已经搞成 DFT结果的数组,针对这部分数据再搞一次傅里叶变换,数学上等同于再做一次傅里叶逆变换。。。 大繁至简的感觉。。所以就看到了处理流程中的IDFT了(离散傅里叶逆变换)。 5、提取变化信息delta delta信息相对于上面的处理就好理解多了。 大家可以回一下导数是怎么求的——后一时刻的值 减去 前一时刻的值 然后,除以时间间隔。 那么到了离散领域, 一阶导数就是一阶delta。 他就是我们上面求的的数组中的每个元素(注意我们上面数组中的每个值其实已经是个向量了),按位和相邻的最近的一个元素相减。 然后,二阶导就是上面求得的一阶导数,再做一次和最近的元素相减的操作。 然后把这两部得到的结果加入进去就完事了。 很简单 6、Finish 经过以上的几部,MFCC最终输出结果为: 一个数组,数组的每个元素是一个39维的向量。 以上便是本章的内容

优秀的个人博客,低调大师

9节基础课程免费公开!

随着数据量的爆发,AI走上风口,典型的大数据业务场景下数据业务最通用的做法是:选用批计算的技术处理全量数据,采用流计算的技术处理实时增量数据。在生产环境中,用户通常采用批处理和流处理两套计算引擎来支持这两种场景。弊端就是需要写两套代码,维护两套引擎,毫无疑问,这种架构带来了额外的负担与成本。 面对全量数据和增量数据,能否用一套统一的大数据引擎技术来处理? Apache Flink 被业界公认为最好的流计算引擎,其计算能力不仅仅局限于做流处理,而是一套兼具流、批、机器学习等多种计算功能的大数据引擎,用户只需根据业务逻辑开发一套代码,无论是全量数据还是增量数据,亦或者实时处理,一套方案即可全部支持。为了让大家更全面地了解 Apache Flink 背后的技术以及应用实践,今天,我们首次免费公开 Apache Flink 系列视频课程。 如何

优秀的个人博客,低调大师

从Python安装到语法基础,这才是初学者都能懂的爬虫教程

Python和PyCharm的安装:学会Python和PyCharm的安装方法 变量和字符串:学会使用变量和字符串的基本用法 函数与控制语句:学会Python循环、判断语句、循环语句和函数的使用 Python数据结构:理解和使用列表、字典、元组和集合 Python文件操作:学习使用Python建立文件并写入数据 Python面向对象:了解Python中类的定义和使用方法 01 Python与PyCharm安装 “工欲善其事,必先利其器”,本节介绍Python环境的安装和Python的集成开发环境(IDE)PyCharm的安装。 Python安装(Windows、Mac和Linux) 当前主流的Python版本为2.x和3.x。由于Python 2第三方库更多(很多库没有向Python 3转移),企业普遍使用Python 2。如果作为学习和研究的话,建议使用Python 3,因为它是未来的发展方向。所以本教程选择Python 3的环境。 1.1 Windows中安装Python 3 在Windows系统中安装Python 3,请参照下面的步骤进行。 打开浏览器,访问Python官网(https://www.python.org/)。 光标移动至Downloads链接,单击Windows链接。 根据自己的Windows版本(32位或64位),下载相应的Python 3.5版本,如为Windows 32位系统,应下载Windows x86 executable installer,如果为Windows 64位系统,应下载Windows x86-64 executable installer。 单击运行文件,勾选Add Python 3.5 to PATH,然后单击Install Now按钮即可完成安装。 在计算机中打开命令提示符(cmd)窗口,输入python,如图1.1所示,说明Python环境安装成功。 ▲图1.1 运行Python环境当界面出现提示符>>>时,就表明进入了Python交互式环境,输入代码后按Enter键即可运行Python代码,通过输入exit()并按Enter键,就可以退出Python交互式环境。 注意:如果出现错误,可能是因为安装时未勾选Add Python3.5 to PATH选项,此时卸载Python后重新安装时勾选Add Python3.5 to PATH选项即可。 1.2 Mac中安装Python3 Mac系统中自带了Python 2.7,需到Python官网上下载并安装Python 3.5。Mac系统中的安装比Windows更为简单,一直单击“下一步”按钮即可完成。安装完后,打开终端并输入python3,即可进入Mac的Python 3的交互式环境。 1.3 Linux中安装Python 3 大部分Linux系统内置了Python 2和Python 3,通过在终端输入python –version,可以查看当前Python 3的版本。如果需要安装某个特定版本的Python,可以在终端中输入: sudo apt-get install python3.5 PyCharm安装 安装好Python环境后,还需要安装一个集成开发环境(IDE),IDE集成了代码编写功能、分析功能、编译功能和调试功能。在这里向读者推荐一个最智能、好用的Python IDE,叫做PyCharm。进入PyCharm的官网,下载社区版即可: http://www.jetbrains.com/pycharm/ 由于PyCharm上手极为简单,因此就不详细讲解PyCharm的使用方法了。以下讲解如何使用PyCharm关联Python解释器,让PyCharm可以运行Python代码。 打开PyCharm,在菜单栏中选择File ∣ Defalut Settings命令。 在弹出的对话框中选择Project Interpreter,然后在右边选择Python环境,这里选择Python 3.5,单击OK按钮,即可关联Python解释器,如图1.2所示。 ▲图1.2 关联Python解释器 02 变量和字符串 本节主要介绍Python变量的概念、字符串的基本使用方法、字符串的切片和索引,以及字符串的几种常用方法。 变量 Python中的变量很好理解,例如: a = 1 这种操作称为赋值,意思为将数值1赋给了变量a。 注意:Python中语句结束不需要以分号结束,变量不需要提前定义。 现在有变量a和变量b,可以通过下面代码进行变量a、b值的对换。 a = 4 b = 5 t = a #把a值赋给t变量 a = b #把b值赋给a变量 b = t #把t值赋给b变量 print(a,b) result 5 4 这种方法类似于将两个杯子中的饮料对换,只需要多加一个杯子,即可完成饮料的对换工作。 字符串的“加法”和“乘法” 由于Python爬虫的对象大部分为文本,所以字符串的用法尤为重要。在Python中,字符串由双引号或单引号和引号中的字符组成。首先,通过下面代码看看字符串的“加法”: a = 'I' b = ' love' c = ' Python' print(a + b + c) #字符串相加 result I love Python 在爬虫代码中,会经常构造URL,例如,在爬取一个网页链接时,只有一部分/u/9104ebf5e177,这部分链接是无法访问的,还需要http://www.jianshu.com,这时可以通过字符串的“加法”进行合并。 注意:此网站为笔者的简书首页。 Python的字符串不仅可以相加,也可以乘以一个数字: a = 'word' print(a*3) #字符串乘法 result wordwordword 字符串乘以一个数字,意思就是将字符串复制这个数字的份数。 字符串的切片和索引 字符串的切片和索引就是通过string[x],获取字符串的一部分信息: a = 'I love python' print(a[0]) #取字符串第一个元素 result I print(a[0:5]) #取字符串第一个到第五个元素 result I lov print(a[-1]) #取字符串最后一个元素 result n 通过图1.3就能清楚地理解字符串的切片和索引。 ▲图1.3 字符串切片和索引 注意:a[0:5]中的第5个是不会选择的。 在爬虫实战中,经常会通过字符串的切片和索引,提取需要的部分,剔除一些不需要的部分。 字符串方法 Python作为面向对象的语言,每个对象都有相应的方法,字符串也一样,拥有多种方法,在这里介绍爬虫技术中常用的几种方法。 4.1 split()方法 a = 'www.baidu.com' print(a.split('.')) result ['www', 'baidu', 'com'] 字符串的split()方法就是通过给定的分隔符(在这里为‘.’),将一个字符串分割为一个列表(后面将详细讲解列表)。 注意:如果没有提供任何分隔符,程序会把所有的空格作为分隔符(空格、制表、换行等)。 4.2 repalce()方法 a = 'There is apples' b = a.replace('is','are') print(b) result There are apples 这种方法类似文本中的“查找和替换”功能。 4.3 strip()方法 a = ' python is cool ' print(a.strip()) result python is cool strip()方法返回去除两侧(不包括内部)空格的字符串,也可以指定需要去除的字符,将它们列为参数中即可。 a = 'python is good' print(a.strip('*!')) result python is good 这个方法只能去除两侧的字符,在爬虫得到的文本中,文本两侧常会有多余的空格,只需使用字符串的strip()方法即可去除多余的空格部分。 4.4 format()方法 最后,再讲解下好用的字符串格式化符,首先看以下代码: a = '{} is my love'.format('Python') print(a) result Python is my love 字符串格式化符就像是做选择题,留了空给做题者选择。在爬虫过程中,有些网页链接的部分参数是可变的,这时使用字符串格式化符可以减少代码的使用量。 例如,Pexels素材网(https://www.pexels.com/),当搜索图片时,网页链接也会发生变化,如在搜索栏中输入book,网页跳转为https://www.pexels.com/search/book/,可以设计如下代码,笔者只需输入搜索内容,便可返回网页链接。 content = input('请输入搜索内容:') url_path = 'https://www.pexels.com/search/{}/'.format(content) print(url_path) 运行程序并输入book,便可返回网页链接,单击网页链接便可访问网页了,如图1.4所示。 ▲图1.4 字符串格式化符演示 03 函数与控制语句 本节主要介绍Python()函数的定义与使用方法,介绍Python的判断和循环两种爬虫技术中常用的控制语句。 函数 “脏活累活交给函数来做”,首先,看看Python中定义函数的方法。 def 函数名(参数1,参数2...): return '结果' 制作一个输入直角边就能计算出直角三角形的面积函数: def function(a,b): return '1/2ab' 也可以这样写 def function(a,b): print( 1/2ab) 注意:读者不需要太纠结二者的区别,用return是返回一个值,而第二个是调用函数执行打印功能。 通过输入function(2,3),便可以调用函数,计算直角边为2和3的直角三角形的面积。现在来做一个综合练习:读者都知道网上公布的电话号码,如156**9354,中间的数值用其他符号代替了,而用户输入手机号时却是完整地输入,下面就通过Python()函数来实现这种转换功能。 def change_number(number): hiding_number = number.replace(number[3:7],''4) print(hiding_number) change_number('15648929354') result 156**9354 注意:这里的手机号码是随意输入的,不是真实的号码。 代码说明如下: 定义了一个名为change_number的函数。 对输入的参数进行切片,把参数的[3:7]部分替换为‘*’号,并打印出来。 调用函数。 判断语句 在爬虫实战中也会经常使用判断语句,Python的判断语句格式如下: if condition: do else: do 注意:冒号和缩进不要忘记了 再看一下多重条件的格式 if condition: do elif condition: do else: do 在平时使用密码时,输入的密码正确即可登录,密码错误时就需要再次输入密码。 def count_login(): password = input('password:') if password == '12345': print('输入成功!') else: print('错误,再输入') count_login() count_login() 程序说明如下: 运行程序,输入密码后按Enter键。 如果输入的字符串为12345,则打印“输入成功!”,程序结束。 如果输入的字符串不是12345,则打印“错误,再输入”,继续运行程序,直到输入正确为止。 读者也可以将程序设计得更为有趣,例如,“3次输入失败后,退出程序”等。 循环语句 Python的循环语句包括for循环和while循环,代码如下: for循环 for item in iterable: do item表示元素,iterable是集合 for i in range(1,11): print(i) 其结果为依次输出1到10,切记11是不输出的,range为Python内置函数 while循环 while condition: do 例如,设计一个小程序,计算1~100的和: i = 0 sum = 0 while i < 100: i = i + 1 sum = sum + i print(sum) result 5050 04 Python数据结构 数据结构是存放数据的容器,本节主要讲解Python的4种基本数据结构,即列表、字典、元组和集合。 列表 在爬虫实战中,使用最多的就是列表数据结构,不论是构造出的多个URL,还是爬取到的数据,大多数都为列表数据结构。下面首先介绍列表最显著的特征: 列表中的每一个元素都是可变的。 列表的元素都是有序的,也就是说每个元素都有对应的位置(类似字符串的切片和索引)。 列表可以容纳所有的对象。 列表中的每个元素都是可变的,这意味着可以对列表进行增、删、改操作,这些操作在爬虫中很少使用,因此这里不再给读者添加知识负担。 列表的每个元素都有对应的位置,这种用法与字符串的切片和索引很相似。 list = ['peter', 'lilei', 'wangwu', 'xiaoming'] print(list[0]) print(list[2:]) result peter ['wangwu', 'xiaoming'] 如果为切片,返回的也是列表的数据结构。 列表可以容纳所有的对象: list = [ 1, 1.1, 'string', print(1), True, [1, 2], (1, 2), {'key', 'value'} ] 列表中会经常用到多重循环,因此读者有必要去了解和使用多重循环。现在,摆在读者面前有两个列表,分别是姓名和年龄的列表: names = ['xiaoming','wangwu','peter'] ages = [23,15,58] 这时可以通过多重循环让name和age同时打印在屏幕上: names = ['xiaoming','wangwu','peter'] ages = [23,15,58] for name, age in zip(names, ages): print(name,age) result xiaoming 23 wangwu 15 peter 58 注意:多重循环前后变量要一致。 在爬虫中,经常请求多个网页,通常情况下会把网页存到列表中,然后循环依次取出并访问爬取数据。这些网页都有一定的规律,如果是手动将这些网页URL存入到列表中,不仅花费太多时间,也会造成代码冗余。这时可通过列表推导式,构造出这样的列表,例如某个网站每页的URL是这样的(一共13页): http://bj.xiaozhu.com/search-duanzufang-p1-0/http://bj.xiaozhu.com/search-duanzufang-p2-0/http://bj.xiaozhu.com/search-duanzufang-p3-0/http://bj.xiaozhu.com/search-duanzufang-p4-0/…… 通过以下代码即可构造出13页URL的列表数据: urls = ['http://bj.xiaozhu.com/search-duanzufang-p{}-0/'.format(number) for number in range(1,14)] for url in urls: print(url) 通过一行代码即可构造出来,通过for循环打印出每个URL,如图1.5所示。 ▲图1.5 列表推导式构造URL列表 注意:本网站为小猪短租网。 字典 Python的字典数据结构与现实中的字典类似,以键值对('key'-'value')的形式表现出来。本文中只讲解字典的创造,字典的操作在后面会详细介绍。字典的格式如下: user_info = { 'name':'xiaoming', 'age':'23', 'sex':'man' } 注意:插入MongoDB数据库需用字典结构。 元组和集合 在爬虫中,元组和集合很少用到,因此这里只做简单介绍。元组类似于列表,但是元组的元素不能修改只能查看,元组的格式如下: tuple = (1,2,3) 集合的概念类似数学中的集合。每个集合中的元素是无序的,不可以有重复的对象,因此可以通过集合把重复的数据去除。 list = ['xiaoming','zhangyun','xiaoming'] set = set(list) print(set) result {'zhangyun', 'xiaoming'} 注意:集合是用大括号构建的。 05 Python文件操作 在爬虫初期的工作中,常常会把数据存储到文件中。本节主要讲解Python如何打开文件和读写数据。 打开文件 Python中通过open()函数打开文件,语法如下: open(name[, mode[, buffering]]) open()函数使用文件名作为唯一的强制参数,然后返回一个文件对象。模式(mode)和缓冲(buffering)是可选参数。在Python的文件操作中,mode参数的输入是有必要的,而buffering使用较少。 如果在本机上有名为file.txt的文件(读者可以在本机中新建一个文本文件),其存储路径为C:UsersAdministratorDesktop,那么可以通过下面代码打开文件: f = open('C:/Users/Administrator/Desktop/file.txt') 注意:此代码为Windows系统下的路径写法。 如果文件不存在,则会出现如图1.6所示的错误。 ▲图1.6 文件不存在报错信息 如果open()函数只是加入文件的路径这一个参数,则只能打开文件并读取文件的相关内容。如果要向文件中写入内容,则必须加入模式这个参数了。下面首先来看看open()函数中模式参数的常用值,如表1.1所示。 ▲表1.1 open()函数中模式参数的常用值 读写文件 上一节中有了名为f的类文件对象,那么就可以通过f.write()方法和f.read()方法写入和读取数据了。 f = open('C:/Users/Administrator/Desktop/file.txt','w+') f.write('hello world') 这时,在本机上打开file.txt文件,可以看到如图1.7所示的结果。 ▲图1.7 Python写文件 注意:如果没有建立文件,运行上面代码也可以成功。 如果再次运行程序,txt文件中的内容不会继续添加,可以修改模式参数为'r+',便可一直写入文件。 Python读取文件通过read()方法,下面尝试把f的类文件对象写入的数据读取出来,使用如下代码即可完成操作: f = open('C:/Users/Administrator/Desktop/file.txt','r') content = f.read() print(content) result hello world 关闭文件 当完成读写工作后,应该牢记使用close()方法关闭文件。这样可以保证Python进行缓冲的清理(出于效率考虑而把数据临时存储在内存中)和文件的安全性。通过下面代码即可关闭文件。 f = open('C:/Users/Administrator/Desktop/file.txt','r') content = f.read() print(content) f.close() 06 Python面向对象 Python作为一个面向对象的语言,很容易创建一个类和对象。本节主要讲解类的定义及其相关使用方法。 定义类 类是用来描述具有相同属性和方法的对象集合。人可以通过不同的肤色划分为不同的种族,食物也有不同的种类,商品也是形形色色。但划分为同一类的物体,肯定具有相似的特征和行为方式。 对于同一款自行车而言,它们的组成结构都是一样的,如车架、车轮和脚踏板等。通过Python可以定义这个自行车的类: class Bike: compose = ['frame','wheel','pedal'] 通过使用class定义一个自行车的类,类中的变量compose称为类的变量,专业术语为类的属性。这样,顾客购买的自行车组成结构就是一样的了。 my_bike = Bike() you_bike = Bike() print(my_bike.compose) print(you_bike.compose) #类的属性都是一样的 结果如图1.8所示。 ▲图1.8 类属性引用 在左边写上变量名,右边写上类的名称,这个过程称之为类的实例化,而my_bike就是类的实例。通过“.”加上类的属性,就是类属性的引用。类的属性会被类的实例共享,所以结果都是一样的。 实例属性 对于同一款自行车来说,有些顾客买回去后会改造下,如加一个车筐可以放东西等。 class Bike: compose = ['frame','wheel','pedal'] my_bike = Bike() my_bike.other = 'basket' print(my_bike.other) #实例属性 结果如图1.9所示。 ▲图1.9 实例属性 说明:通过给类的实例属性进行赋值,也就是实例属性。compose属性属于所有的该款自行车,而other属性只属于my_bike这个类的实例。 实例方法 读者是否还记得字符串的format()方法。方法就是函数,方法是对实例进行使用的,所以又叫实例方法。对于自行车而言,它的方法就是骑行。 class Bike: compose = ['frame','wheel','pedal'] def use(self): print('you are riding') my_bike = Bike() my_bike.use() 结果如图1.10所示。 ▲图1.10 实例方法 注意:这里的self参数就是实例本身。 和函数一样,实例方法也是可以有参数的。 class Bike: compose = ['frame','wheel','pedal'] def use(self,time): print('you ride {}m'.format(time*100)) my_bike = Bike() my_bike.use(10) 结果如图1.11所示。 ▲图1.11 实例方法多参数 Python的类中有一些“魔法方法”,_init_()方法就是其中之一。在我们创造实例的时候,不需要引用该方法也会被自动执行。 class Bike: compose = ['frame','wheel','pedal'] def __init__(self): self.other = 'basket' def use(self,time): print('you ride {}m'.format(time*100)) my_bike = Bike() print(my_bike.other) 结果如图1.12所示。 ▲图1.12 魔术方法 类的继承 共享单车的出现,方便了人们的出行。共享单车和原来的自行车组成结构类似,但多了付费的功能。 class Bike: compose = ['frame','wheel','pedal'] def __init__(self): self.other = 'basket' #定义实例的属性 def use(self,time): print('you ride {}m'.format(time*100)) class Share_bike(Bike): def cost(self,hour): print('you spent {}'.format(hour*2)) bike = Share_bike() print(bike.other) bike.cost(2) 结果如图1.13所示。 ▲图1.13 类的继承 在新的类Share_bike后面的括号中加入Bike,表示Share_bike继承了Bike父类。父类中的变量和方法可以完全被子类继承,在特殊情况下,也可以对其覆盖

优秀的个人博客,低调大师

全志A33开发板的安卓控制LED-2-JNI基础

虽然您可以完全使用Java编写应用程序,但有些情况下Java本身并不能满足您的应用程序的需求。当应用程序不能完全用Java编写时,程序员使用JNI编写Java本机方法来处理这些情况。以下示例说明何时需要使用Java本机方法: 标准Java类库不支持应用程序所需的与平台相关的功能。您已经有一个用另一种语言编写的库,并希望通过JNI使其可以访问Java代码。您希望在较低级别的语言(如汇编语言)中实现一小部分时间关键代码。来源:https://docs.oracle.com/javase/1.5.0/docs/guide/jni/ 开发平台 芯灵思SinlinxA33开发板 了解JNI函数 JNI函数就是在native层定义的本地函数,对应于在java层使用native关键字声明的方法的。直白的说,就是在Java层声明,C/C++语言实现的。当然,这个函数并不一般,它会通过JNI某种机制与Java层的方法进行关联,使得Java层代码可以很方便的调用它。 jni函数的语法和调用规则 将java语言的数据类型转换成底层语言调用规则 将java语言的方法调用转换成底层语言函数或方法 jni数据类型的转化 jni在java和C之间建立连接,因此jni首先要统一两者的数据类型 Java Type Native Type Description boolean jboolean unsigned 8 bits byte jbyte signed 8 bits char jchar unsigned 16 bits short jshort signed 16 bits int jint signed 32 bits long jlong signed 64 bits float jfloat 32 bits double jdouble 64 bits void void N/A The following definition is provided for convenience. define JNI_FALSE 0 #define JNI_TRUE 1 The jsize integer type is used to describe cardinal indices and sizes:typedef jint jsize; java中可以直接调用底层语言的函数,jni规定了java调用底层语言的方法签名 java中有重载概念,所以java方法转换成签名,签名再转化为函数 Type Signature Java Type Z boolean B byte C char S short I int J long F float D double L fully-qualified-class [ type type[] For example, the Java method:long f (int n, String s, int[] arr); has the following type signature:(ILjava/lang/String;[I)J jni机制实现 native 声明的函数可以不实现 class Cls { native double f(int i, String s); // 声明为本地方法 static { System.loadLibrary(“库名”); // 通过静态初始化语句块来加载动态库 } } 程序实现测试java代码javah -jni Hello 生成Hello .h 打开Hello .h 文件里面已经写好C函数的名字C代码将C文件制做成共享库.so,注意指定jni.h和jni_md.h文件路径 gcc -shared -fPIC hello.c -o libhello.so -I /usr/java/jdk1.6.0_45/include/ -I /usr/java/jdk1.6.0_45/include/linux/ java Hello 运行程序实验现象

优秀的个人博客,低调大师

Python零基础学习代码实践 —— 提取字符串里面的单词数

str = input() str1 = str.strip() index = 0 count = 0 while index < len(str1): while str1[index] != " ": index += 1 if index == len(str1): break count += 1 if index == len(str1): break while str1[index] == " ": index += 1 print(count) 执行结果 C:\Users\Administrator\AppData\Local\Programs\Python\Python37-32\python.exe C:/Users/Administrator/PycharmProjects/untitled/day005/提取字符转里面的单词数.py 4 Process finished with exit code 0

优秀的个人博客,低调大师

高可用架构篇--MyCat在MySQL主从复制基础上实现读写分离

点击链接加入群【Dubbo技术交流2群】:https://jq.qq.com/?_wv=1027&k=46DcDFI 一、环境 操作系统:CentOS-6.6-x86_64-bin-DVD1.iso JDK版本:jdk1.7.0_45 MyCat版本:Mycat-server-1.4-release-20151019230038-linux.tar.gz MyCat节点IP:192.168.1.203 主机名:edu-mycat-01 主机配置:4核CPU、4G内存 MySQL版本:mysql-5.6.26.tar.gz 主节点IP:192.168.1.205 主机名:edu-mysql-01 主机配置:4核CPU、4G内存 从节点IP:192.168.1.206 主机名:edu-mysql-02 主机配置:4核CPU、4G内存 二、依赖课程 《高可用架构篇--第13节--MySQL源码编译安装(CentOS-6.6+MySQL-5.6)》 《高可用架构篇--第14节--MySQL主从复制的配置(CentOS-6.6+MySQL-5.6)》 注意:上一节课中讲到的MySQL主从复制配置,在用MyCat做主从读写分离或其结合实际项目场景应用中,主从复制配置还需要按实际需求情况进行调整。 (调整后的主从数据库my.cnf配置文件,随视频教程压缩包提供) 三、MyCat介绍 ( MyCat官网:http://mycat.org.cn/ ) MyCat的读写分离是基于后端MySQL集群的主从同步来实现的,而MyCat提供语句的分发功能。MyCat1.4开始支持MySQL主从复制状态绑定的读写分离机制,让读更加安全可靠。 四、MyCat的安装 1、设置MyCat的主机名和IP与主机名的映射 # vi /etc/sysconfig/network NETWORKING=yes HOSTNAME=edu-mycat-01 # vi /etc/hosts 127.0.0.1 edu-mycat-01 192.168.1.203 edu-mycat-01 192.168.1.205 edu-mysql-01 192.168.1.206 edu-mysql-02 2、因为MyCat是用Java开发的,因此MyCat运行需要安装JDK(准确来说是JRE就够了),并且需要JDK1.7或以上版本 # vi /etc/profile ## java env export JAVA_HOME=/usr/local/java/jdk1.7.0_72 export JRE_HOME=$JAVA_HOME/jre export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib/rt.jar export PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin # source /etc/profile # java -version 3、创建mycat用户并设置密码 # useradd mycat # passwd mycat 4、上传安装包 Mycat-server-1.4-release-20151019230038-linux.tar.gz 到 MyCat服务器中的/home/mycat目录,并解压并移动到 /usr/local/mycat目录 $ tar -zxvf Mycat-server-1.4-release-20151019230038-linux.tar.gz $ su root Password: # mv /home/mycat/mycat /usr/local/ # cd /usr/local/mycat/ # ll 5、设置MyCat的环境变量 # vi /etc/profile ## mycat env export MYCAT_HOME=/usr/local/mycat export PATH=$PATH:$MYCAT_HOME/bin # source /etc/profile 五、配置MyCat 1、在配置MyCat前,请确认MySQL的主从复制安装配置已完成并正常运行。MySQL主从数据的同步在MySQL中配置,MyCat不负责数据同步的问题。 补充: (1) MySQL主从复制配置中,如果涉及到函数或存储过程的同步复制,需要在/etc/my.cnf中的[mysqld]段中增加配置 log_bin_trust_function_creators=true 或在客户端中设置 set global log_bin_trust_function_creators = 1; (2) 如果要做读写分离下的主从切换,那么从节点也有可能会变为写节点,因此从节点就不能设置为只读 read_only=1 。 (3) Linux版本的MySQL,需要设置为MySQL大小写不敏感,否则可能会发生找不到表的问题。可在/etc/my.cnf的[mysqld]段中增加 lower_case_table_names=1 。 2、配置MyCat的schema.xml schema.xml是MyCat最重要的配置文件之一,用于设置MyCat的逻辑库、表、数据节点、dataHost等内容, [mycat@edu-mycat-01 conf]$ cd /usr/local/mycat/conf/ [mycat@edu-mycat-01 conf]$ vi schema.xml <?xml version="1.0"?> <!DOCTYPE mycat:schema SYSTEM "schema.dtd"> <mycat:schema xmlns:mycat="http://org.opencloudb/"> 定义MyCat的逻辑库,逻辑库的概念与MySQL中的 database 概念相同 --> "rc_schema1" checkSQLschema="false" sqlMaxLimit="100" dataNode="rc_dn1"> "pay_schema1" checkSQLschema="false" sqlMaxLimit="100" dataNode="pay_dn1"> <schema name="rc_schema2" checkSQLschema="false" sqlMaxLimit="100" dataNode="rc_dn2">schema> <schema name="pay_schema2" checkSQLschema="false" sqlMaxLimit="100" dataNode="pay_dn2">schema> 其中checkSQLschema表明是否检查并过滤SQL中包含schema的情况,如逻辑库为 TESTDB,则可能写为select * from TESTDB.edu_user,此时会自动过滤TESTDB,SQL变为select * from edu_user,若不会出现上述写法,则可以关闭属性为false --> 默认返回的最大记录数限制,MyCat1.4版本里面,用户的Limit参数会覆盖掉MyCat的sqlMaxLimit默认设置--> 定义MyCat的数据节点 --> "rc_dn1" dataHost="dtHost1" database="roncoo" / --> "pay_dn1" dataHost="dtHost1" database="edu_simple_pay" / --> <dataNode name="rc_dn2" dataHost="dtHost2" database="roncoo" /> <dataNode name="pay_dn2" dataHost="dtHost2" database="edu_simple_pay" /> 中的 name 数据表示节点名称, dataHost表示数据主机名称, database表示该节点要路由的数据库的名称 --> 配置的是实际的后端数据库集群(当然,也可以是非集群) --> 注意:schema中的每一个dataHost中的host属性值必须唯一,否则会出现主从在所有dataHost中全部切换的现象 --> 定义数据主机dtHost1,只连接到MySQL读写分离集群中的Master节点,不使用MyCat托管MySQL主从切换 -->      "dtHost1" maxCon="500" minCon="20" balance="0"           writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">          select user()          "hostM1" url="192.168.1.205:3306" user="root" password="www.roncoo.com" />           --> 使用MyCat托管MySQL主从切换 --> 定义数据主机dtHost2,连接到MySQL读写分离集群,并配置了读写分离和主从切换 --> <dataHost name="dtHost2" maxCon="500" minCon="20" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="2" slaveThreshold="100"> 通过show slave status检测主从状态,当主宕机以后,发生切换,从变为主,原来的主变为从,这时候show slave                  status就会发生错误,因为原来的主没有开启slave,不建议直接使用switch操作,而是在DB中做主从对调。 --> <heartbeat>show slave statusheartbeat> multi write hosts --> <writeHost host="hostM2" url="192.168.1.205:3306" user="root" password="www.roncoo.com" /> <writeHost host="hostS2" url="192.168.1.206:3306" user="root" password="www.roncoo.com" /> dataHost> 参数balance决定了哪些MySQL服务器参与到读SQL的负载均衡中 --> ,为不开启读写分离,所有读操作都发送到当前可用的writeHost上--> ,全部的readHost与stand by writeHost参与select语句的负载均衡--> ,所有读操作都随机的在writeHost、readHost上分发--> 版本中,若想支持MySQL一主一从的标准配置,并且在主节点宕机的情况下,从节点还能读取数据,则需要在MyCat里配置为两个writeHost并设置balance="1" --> ,所有写操作都发送到可用的writeHost上 --> ,仅仅对于galera for mysql集群这种多主多节点都能写入的集群起效,此时Mycat会随机选择一个writeHost并写入数据,对于非galera for mysql集群,请不要配置writeType=1,会导致数据库不一致的严重问题 --> mycat:schema> MyCat1.4开始支持MySQL主从复制状态绑定的读写分离机制,让读更加安全可靠,配置如下: MyCat心跳检查语句配置为 show slave status ,dataHost 上定义两个新属性:switchType="2" 与 slaveThreshold="100",此时意味着开启MySQL主从复制状态绑定的读写分离与切换机制,MyCat心跳机制通过检测 show slave status 中的 "Seconds_Behind_Master", "Slave_IO_Running", "Slave_SQL_Running" 三个字段来确定当前主从同步的状态以及Seconds_Behind_Master主从复制时延,当Seconds_Behind_Master 大于slaveThreshold时,读写分离筛选器会过滤掉此Slave机器,防止读到很久之前的旧数据,而当主节点宕机后,切换逻辑会检查Slave上的Seconds_Behind_Master是否为0,为0时则表示主从同步,可以安全切换,否则不会切换。 3、配置 server.xml server.xml 主要用于设置系统变量、管理用户、设置用户权限等。 [wusc@edu-mycat-01 conf]$ vi server.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mycat:server SYSTEM "server.dtd"> <mycat:server xmlns:mycat="http://org.opencloudb/"> <system> <property name="defaultSqlParser">druidparserproperty> <property name="charset">utf8mb4property> 1--> 为开启mysql压缩协议--> 40960-->      1     32       --> 默认是65535 64K 用于sql解析时最大文本长度 --> 65535--> 0--> 1--> 1--> 16--> 10:开启小数量级(默认) ;1:开启亿级数据排序                 100亿级数量排序批量                3232                80669066                3000000.0.0.0                409632           --> system> 用户1,对应的MyCat逻辑库连接到的数据节点对应的主机为MySQL主从复制配置中的Master节点,没实现读写分离,读写都在该Master节点中进行  -->      "user1">          "password">roncoo.1          "schemas">rc_schema1,pay_schema1           --> 用户2,对应的MyCat逻辑库连接到的数据节点对应的主机为主从复制集群,并通过MyCat实现了读写分离 --> <user name="user2"> <property name="password">roncoo.2property> <property name="schemas">rc_schema2,pay_schema2property> user> 用户3,只读权限--> <user name="user3"> <property name="password">roncoo.3property> <property name="schemas">rc_schema2,pay_schema2property> <property name="readOnly">trueproperty> user> mycat:server> 4、防火墙中打开8066和9066端口 MyCat的默认数据端口为8066,mycat通过这个端口接收数据库客户端的访问请求。 管理端口为9066,用来接收mycat监控命令、查询mycat运行状况、重新加载配置文件等。 [root@edu-mycat-01 mycat]# vi /etc/sysconfig/iptables 增加: ## MyCat -A INPUT -m state --state NEW -m tcp -p tcp --dport 8066 -j ACCEPT -A INPUT -m state --state NEW -m tcp -p tcp --dport 9066 -j ACCEPT 重启防火墙: [root@edu-mycat-01 mycat]# service iptables restart 5、修改log日志级别为debug,以便通过日志确认基于MyCat的MySQL数据库集群读写分离的数据操作状态(可以在正式上生产前改成info级别) [mycat@edu-mycat-01 conf]$ vi /usr/local/mycat/conf/log4j.xml 6、启动MyCat [mycat@edu-mycat-01 bin]$ cd /usr/local/mycat/bin/ (1) 控制台启动,这种启动方式在控制台关闭后,MyCat服务也将关闭,适合调试使用: [mycat@edu-mycat-01 bin]$ ./mycat console (2) 可以采用以下后台启动的方式: [mycat@edu-mycat-01 bin]$ ./mycat start Starting Mycat-server... (对应的,重启: mycat restart , 关闭: mycat stop ) 7、MyCat连接测试 (1) 如果本地Windows安装有MySQL,可以使用已有的mysql客户端远程操作MyCat (2) 如果为了方便,需要在MyCat主机上对MyCat进行操作(把MyCat当是本地MySQL来操作),可以在MyCat节点主机上安装MySQL客户端: [mycat@edu-mycat-01 bin]$ su root [root@edu-mycat-01 bin]# yum install mysql 使用安装好的mysql客户端登录MyCat [mycat@edu-mycat-01 bin]$ mysql -uuser2 -proncoo.2 -h192.168.1.203 -P8066 [root@edu-mycat-01 mycat]# vi /etc/my.cnf 增加: [client] default-character-set=utf8 保存后再查询,乱码问题解决,如下: (3) 使用第三方MySQL管理客户端连接MyCat测试(navicat支持,MySQL-Front兼容性不太好),以navicat为例: 8、读写分离测试 (1) 监听MyCat日志 [mycat@edu-mycat-01 ~]$ cd /usr/local/mycat/logs/ [mycat@edu-mycat-01 logs]$ tail -f mycat.log (2) 读测试 $ mysql -uuser2 -proncoo.2 -h192.168.1.203 -P8066 mysql> show databases; mysql> use rc_schema2; mysql> show tables; mysql> select * from edu_user; 执行上面的查询语句,此时对应的MyCat日志信息如下: 多次执行 select * from edu_user 语句,MyCat打印出来的日志信息显示读操作请求都是路由到Slave节点(192.168.1.206)。 (2) 写测试 mysql> insert into edu_user (userName, pwd) values('吴水成', 'roncoo.com'); 执行上面的新增插入语句后,此时对应的MyCat日志信息如下: 多次执行以上插入语句,发现新增数据都是从 Master节点(192.168.1.205)插进入的,并且Slave节点通过Binlog同步了Master节点中的数据。 综上,基于MyCat的读写分离集群配置成功。 接下来计划课程: MyCat读写分离集群的主从容错(切换)、恢复; MyCat的高可用集群 HAProxy + Keepalived + MyCat; 关注微信:

优秀的个人博客,低调大师

Python爬虫基础学习,从一个小案例来学习xpath匹配方法

学习目的是为了实践,而实践又可以加深我们的学习效率,今天给大家带来了lxml库的xpath匹配方法的实例!教程大家网上搜索有很多,我们只看实用功能,当然,如果您已经很熟练了,可以跳过不看的! 开始前准备 版本:python3.6 工具:pycharm、lxml库(pip安装即可) 内容:新浪新闻搜索关键字抓取相关信息并保存本地txt文档 思路 我们先打开网页url,看下它的页面数据是怎么加载的 搜索世界杯,然后在开发者工具中先抓包看看是否为json数据,结果发现并没有,那么直接打开源代码看看呢 源代码往下翻,到1200行左右看内容,眼熟不?所有的新闻都在源代码中存在,那么就简单了!直接可以抓取相关内容 开始写代码吧 先介绍一下xpath的语法,其实各种教程都有写,我们只需要记住几点 它解析网页源代码的语法为etree.HTML(html)#html为网页源代码的文本形式 它的匹配方式为data.xpath(‘//a[@class=*]/text()’)#data为上步解析后的源码或者指定源码 它匹配出来的结果为列表 尽量不要用开发者工具提供的复制xpath路径功能,因为它对于后期维护或者修改你的代码很不友好 ok,不啰嗦了,直接上代码了 可以看到几行代码直接获取了所有新闻的标题,简单说一下那几行代码 1、url,有人可能已经注意到了,我在代码中用的url和网页实际的有些不同,那是因为url中?后面的内容,如果&后面的参数没有结果的话,是可以省略的,还有可以省略的就是类似时间戳等等,大家可以尝试下! 2、html = requests.get(url)常规的获取网页源代码,用的是requests库,因为这个网站没有反爬,所以很容易就取到了 3、data = etree.HTML(html.text)这里就是上文所说,解析源码的语法,而且lxml解析源码还一个好处就是,如果源码中存在非闭合的标签或者不是很规范的标签,它会自动补全,非常实用! 4、重点来了:infos = data.xpath(‘//div[@class=”r-info r-info2”]/h2/a’)这行代码是获取源代码中带有”r-info r-info2”值的class属性,并且它在div标签中,然后在标签内容中查找h2标签及h2标签下的a标签,我们来看看网页中的位置 这里需要注意的是,尽量选择用class属性去定位是比较好的,因为它的属性一般都是功能唯一的,比较方便!大家可以先复制属性值然后去源代码中搜索,如果唯一或者所在的标签全部是需要的内容,那么就可以使用,如果不是,请往上级查找! 5、因为刚才定位到的标签是列表形式,所以用for循环来遍历取出,这里重点讲解下string(.)的用法: 上面的标签内容是非常方便的,标题就在a标签下的文本中,但是依然存在一种情况,比如标题中含有我们是搜索的关键字的时候,它就不是只存在a标签下了,比如下图 短短一行,存在2个标签,a和a标签下的span标签,那么这种情况下,我们就需要使用string(.)来匹配了,它的主要功能是取出所属标签下所有文本内容!所以我们的语法就成了info.xpath(‘string(.)’,然后用print显示就达到了效果! 好了,语法大概说到这,我们将所有的标题和url、简介全部抓取下来,然后写到txt文档,篇幅有限就抓5页的内容吧! ok,内容全部写到文件了,当然了,还可以继续往下写,比如进入每一个新闻页面,抓取所有文本内容,也是一样的写法,大家有兴趣的可以自行完善哦! 最后 推荐一个我个人的学习方法,那就是多看多听多练!多看看大神的教程、博客、经验总结等等,多听听大神的思路分析,最重要的是多练,代码一定要多写!代码一定要多写!代码一定要多写!这样才能更快的学习进步!!大家加油

优秀的个人博客,低调大师

Windows 容器基础知识扫盲问答,权威 Docker 专家为您扫清认知障碍!

本文首发自“Docker公司”公众号(ID:docker-cn)编译丨小东每周一、三、五 与您不见不散! 最近举办的 Docker 线上活动 —— 演示了 Docker EE 2.0版本,让我们有机会强调在整个应用程序组合中采用容器化策略的一些重要原因。在上一篇文章中(Docker 线上活动问题汇总,九问九答助您了解 Docker EE 2.0版本),我们解答了在使用 Docker 企业版(世界领先的企业级容器平台)的过程中所收集到的有关 Swarm 和 Kubernetes 编排的一些重要问题。今天,我们将解答有关运行 Windows 容器的相关问题。 如果您错过了现场活动,请不要担心!您可以浏览 https://register.gotowebinar.com/rt/1425169769433669891 查阅相关资料。 Docker 企业版:唯一完全支持在 Windows Server 2016 上运行容器的解决方案。 问:据我所知容器基于的是 Linux 进程,那么 Docker 容器又是如何基于 Windows 进行工作的呢? 答:Docker 自 2014 年以来就一直在与微软进行合作,并将 Docker 容器的优势交付到 Windows Server 中,以至于客户可以很轻松的在 Docker 容器中运行 .NET 和 IIS 应用程序。我们通力协作对 Windows Server 内核进行调整以支持容器化基元、增加对 Docker 引擎和 CLI 的支持以及为 Windows 镜像增加了多架构支持。其结果是,原生的 Docker 容器可以在 Windows Server 2016 上运行,并利用与基于 Linux 环境中的 Powershell 相同的 CLI 命令。 问:Windows Server 是否支持 Kubernetes? 答:对 Kubernetes 中的 Windows Server 容器的支持目前还处于测试阶段,预计今年晚些时候将提供全面支持。要在生产环境中运行 Windows Server 容器,Docker EE 2.0 版本的客户可以使用 Docker Swarm 来部署这些工作负载,这个功能早在一年前就可以使用了。 问:可以运行完整的 Windows Server 群集吗? 答:使用 Docker EE 2.0 版本,您可以运行混合了 Linux 和 Windows Server 2016 的工作节点或包含全部 Windows Server 工作节点的群集。请注意,即使您正在运行的全部都是 Windows Server 工作节点,Docker EE 2.0 版本管理栈也会部署到基于 Linux 的节点上。对于我们的许多 Windows 商店的企业客户来说,他们将这些管理节点部署在具有 Linux 操作系统的 Hyper-V 虚拟机上。 问:在同一个环境中,Windows 和 Linux 容器可以相互通信吗? 答:可以!同一群集中的 Windows 和 Linux 容器可以共享一个通用覆盖网络。 问:是否支持 Windows Server 1709 或 Windows Server 1803? 答:对 Windows Server 1709 和 Windows Server 1803 的支持将在 2018 年第二季度发布。 问:对 Docker EE 2.0 版本和 Windows Server 的授权是如何进行的? 答:虽然 Windows Server 2016 中包含了 Docker EE 2.0 Basic (即 Docker EE 引擎),但是像提供统一管理 UI 和私有镜像仓库这类 Docker EE 的标准和高级功能,就需要额外的许可证了。请与销售部门联系(https://goto.docker.com/contact-us.html), 了解更多关于定价和许可的信息。 问:我的 .NET 开发团队构建容器化应用程序时可以适用于什么解决方案? 答:除了 Docker for Mac,Docker 还提供 Docker for Windows —— 即用于本地容器开发的免费桌面版解决方案。有两个版本的 Docker for Windows,其中尝鲜版本包含了一个独立的 Kubernetes 服务器和客户端,以及 Docker CLI 集成。Kubernetes 服务器在本地的 Docker 实例中运行,这样您的 .NET 开发人员就可以在本地使用 Swarm 和 Kubernetes 了。

资源下载

更多资源
优质分享App

优质分享App

近一个月的开发和优化,本站点的第一个app全新上线。该app采用极致压缩,本体才4.36MB。系统里面做了大量数据访问、缓存优化。方便用户在手机上查看文章。后续会推出HarmonyOS的适配版本。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册