本教程所有源码下载链接:https://share.weiyun.com/5xmFeUO 密码:fzwh6g
基础知识
环境搭建
Python安装
平时能接触到的操作系统非Windows、macOS、Linux莫属。其中Windows是我们日常中最常用的OS,它软件更多、办公和游戏可以兼得;macOS由于搭载其的电脑外表漂亮、屏幕优秀、性能均衡,而被很多设计者和程序员所喜爱;Linux在服务器领域是无可匹敌,几乎所有大型应用服务器都部署于Linux系统,常用的Linux服务器系统有CentOS、Ubuntu Server等,但是Linux桌面版也在程序员中应用较广,便捷的终端、稳定的性能是编程的首选。
由于macOS和Ubuntu系统都自带python环境,因此,我们只讲解Windows下Python的安装和配置。感兴趣的同学,可以自己在虚拟机中测试和熟悉Linux系统,推荐Ubuntu18.04。
Windows下安装Python
熟悉一下Python的主页:
下载。官方的最新版已经更新到了3.7.0,但是我们下载的版本是Python3.6.5,因此,我们点击View the full list of downloads。
只需要记住,不同架构的Windows系统,选择不同的安装包下载。
安装。按图示操作即可。
双击安装包,选择自定义安装,方便以后使用。
直接下一步。
修改路径,将路径改为
c:\Python36
。安装成功
环境变量检测与设置。
打开cmd命令行。
输入
python
,提示python版本等信息表示环境变量设置成功。如果输入python后,提示不是内部命令或外部命令,则表示环境变量没有配置好。
设置环境变量。
桌面右击
计算机
🖥️,选择属性,然后,再次选择高级系统设置
。在
高级
一栏中点击环境变量
,打开环境变量
设置窗口。点击
新建
,在变量名中输入PATH
(大写),在变量值中输入C:\Python36\Scripts\;C:\Python36\
,C:\Python36\Scripts\
文件夹下有一些常用工具,例如pip
包管理工具,也加入到环境变量中,这样方便以后使用;C:\Python36\
就是python的安装目录。将cmd命令行都关闭,重新打开cmd,再次输入
python
进行验证。
Python环境到这里就安装完毕了。
包管理工具pip
pip是Python的一款包管理工具,由于众所周知的原因,用pip安装库的速度简直是“是可忍孰不可忍”。因此,我们有必要加速pip包管理工具的下载速度。
pip的基本使用
Windows中,打开cmd命令行,输入pip
后,可以看到使用方法:
1 | # 搜索requests包 |
升级pip包管理器
1 | python -m pip install --upgrade pip |
加速pip下载速度
在某程序员论坛上,有这样一个软笑话:《安装scrapy快疯了,一个下午没了》😄️
我们使用清华大学开源软件镜像站的pypi镜像进行pip下载加速。
临时加速
1 | pip install -i https://pypi.tuna.tsinghua.edu.cn/simple requests |
注意,
simple
不能少,是https
而不是http
永久加速1
修改
~/.config/pip/pip.conf
(Linux),
%APPDATA%\pip\pip.ini
(Windows 10) ,
C:\Users\Administrator\AppData\Roaming\pip\pip.ini
(Windows7),
$HOME/Library/Application Support/pip/pip.conf
(macOS) (没有就创建一个),
修改 index-url
至tuna,例如
1 | [global] |
pip 和 pip3 并存时,只需修改 ~/.pip/pip.conf
。
永久加速2
使用脚本永久加速,只需用Python执行oh-my-tuna.py
文件即可设置好镜像站加速,
该脚本在我们的源码中有提供,位置为CrawlerLessons/codes/lesson01/oh-my-tuna.py
,下载后,直接在命令行中运行即可:
1 | python on-my-tuna.py |
安装IPython
ipython
是一个python
的交互式shell
,比默认的python shell
好用得多,支持变量自动补全,自动缩进,支持bash shell
命令,内置了许多很有用的功能和函数。学习ipython
将会让我们以一种更高的效率来使用python
。同时它也是利用Python进行科学计算和交互可视化的一个最佳的平台。
使用pip
安装IPython
:
1 | pip install ipython |
使用IPython
,再命令行中输入ipython
即可进入交互式shell
:
1 | ╭─sunjiajia@Mac /Users/sunjiajia ‹system› |
IDE 的选择
在以后的编程中,我们使用PyCharm
这款享誉全球的IDE,开发、调试、支持网页开发和支持数据库,可以满足我们几乎所有的开发需求。
PyCharm
是收费软件,但也提供社区免费版本,虽然功能有所减少,但是也够我们后续写爬虫了。
PyCharm
下载地址:官方网址。
PyCharm的基本使用
创建项目:
选择项目路径:
创建Python文件,命名为test01.py
:
在test01.py
中输入以下python代码,右击空白处,选择Run test01
,运行当前python文件:
PyCharm常用设置项如图所示:
HTML和CSS基础知识
这一节我们学习网页编程的基础知识。这节课目标是,了解网页的基本知识,在写爬虫的时候可以清晰的分析目标数据所在的结构,从而更轻松的拿到自己想要的数据。
无论是动态加载,还是延迟加载,无论是文字还是多媒体,最终在浏览器中展示给我们,都是以HTML语法来展示;无论是绚丽的动画页面效果,还是表格的样式,都可以用CSS来进行定制。
下面来一个概念简介,来自百度百科的内容:
HTML,即超文本标记语言(英语:HyperText Markup Language),是标准通用标记语言下的一个应用,也是一种规范,一种标准,它通过标记符号来标记要显示的网页中的各个部分。网页文件本身是一种文本文件,通过在文本文件中添加标记符,可以告诉浏览器如何显示其中的内容(如:文字如何处理,画面如何安排,图片如何显示等)。
CSS,即层叠样式表(英文全称:Cascading Style Sheets),是一种用来表现HTML或XML等文件样式的计算机语言。CSS不仅可以静态地修饰网页,还可以配合各种脚本语言动态地对网页各元素进行格式化。
HTML基本标签
标签名 | 含义 |
---|---|
<!--...--> |
注释标签用于在源代码中插入注释。注释不会显示在浏览器中。 |
<!DOCTYPE> |
<!DOCTYPE> 声明必须是 HTML 文档的第一行,位于 <html> 标签之前。<!DOCTYPE> 声明不是 HTML 标签;它是指示 web 浏览器关于页面使用哪个 HTML 版本进行编写的指令。在 HTML5 中只有一种写法<!DOCTYPE html> |
<html> |
<html> 与 </html> 标签限定了文档的开始点和结束点,在它们之间是文档的头部和主体。正如您所了解的那样,文档的头部由 <head> 标签定义,而主体由<body> 标签定义。 |
<head> |
用于定义文档的头部,它是所有头部元素的容器。<head> 中的元素可以引用脚本、指示浏览器在哪里找到样式表、提供元信息等等。 |
<meta> |
提供有关页面的元信息(meta-information),比如针对搜索引擎和更新频度的描述和关键词。 |
<title> |
定义文档的标题。 |
<style> |
用于为 HTML 文档定义样式信息。type 属性是必需的,定义 style 元素的内容。唯一可能的值是 "text/css" 。 |
<link> |
定义文档与外部资源的关系,最常见的用途是链接样式表。 |
<body> |
body 元素定义文档的主体,包含文档的所有内容(比如文本、超链接、图像、表格和列表等等。) |
HTML常用标签
标签名 | 含义 |
---|---|
<a href="http://news.baidu.com/" target="_blank">新闻</a> |
定义超链接 |
<img src="images/logo.png" alt="GitOPEN搜索,最贴心搜索"> |
插入图片 |
<table border="1"><tr><th>Month</th><th>Savings</th></tr><tr><td>January</td> <td>$100</td></tr></table> |
表格 |
<div>我是div</div> |
可定义文档中的分区或节 |
<p><span>some text.</span>some other text.</p> |
被用来组合文档中的行内元素。 |
<ul><li>Coffee</li><li>Milk</li></ul> |
无序列表 |
<ol><li>Coffee</li><li>Milk</li></ol> |
有序列表 |
<input type="button" value="搜索一下"/> |
用于搜集用户信息。根据不同的 type 属性值,输入字段可以是text 、复选框checkbox 、单选按钮radio 、button 、submit 等等。 |
CSS语法
HTML整合CSS的方式一
直接将css写在HTML文件中,代码CrawlerLessons/codes/lesson01/HTMLDemo/demo01.html
1 |
|
HTML整合CSS的方式二
css写在单独的文件中,代码CrawlerLessons/codes/lesson01/HTMLDemo/demo02.css
1 | #div01 { |
html也是一个单独的文件,代码CrawlerLessons/codes/lesson01/HTMLDemo/demo02.html
1 |
|
CSS常用属性
属性名 | 作用 |
---|---|
font-size | 字号大小 |
font-style | 字体格式 |
font-weight | 字体粗细 |
color | 文本颜色 |
text-decoration | 超链接设置。line-through添加删除线;blink文字闪动;none不显示上述任何效果 |
background-color | 背景颜色 |
backgroud-image | 背景图片(地址) |
background-repeat | 是否重复。no-repeat不重复平铺;repeat-x或者y:只在水平或者垂直方向上平铺 |
text-align | 文本对齐。left左对齐;right右对齐;center居中对齐;justify:相对左右两端对齐 |
display | 显示样式。block块级元素,在对象前后都换行;inline在对象前后都不换行;list-item在对象前后都换行,增加了项目符号 |
Python必备知识点
基础数据类型
变量及其类型的含义
Python中的变量不需要声明,变量在使用前都必须赋值,在赋值以后,该变量才会被创建。
Python中的变量就是变量,它本身没有类型,通常所说的“变量类型”,表示的意思是变量所指向的内存中对象的类型。
1 | name = 'GitOPEN' |
等号(=)叫做运算符,用来给变量name
、age
、salary
赋值,左边是一个变量名,右边是存储在变量中的值。
在给变量赋值不同类型的对象,那么,变量就有了类型。
name
是字符串变量,age
是整型变量,salary
是浮点型变量。
多个变量赋值
Python中,可以同时为多个变量赋值:
1 | aa = bb = cc = 11 |
这个例子的含义为,创建一个整型对象,值为11,从后向前赋值,3个变量都指向同一个内存地址。
再看一个例子:
1 | dd, ee, ff = 22, 33, "GitOPEN" |
这个例子中,将整型对象22
和33
分别分配给变量dd
和ee
,字符串对象GitOPEN
分配给变量ff
。
标准数据类型
- Number(数字)── 不可变数据
- String(字符串)──不可变数据
- List(列表)──可变数据
- Tuple(元组)──不可变数据
- Set(集合)──可变数据
- Dictionary(字典)──可变数据
Number(数字)
Python3中的支持int、float、bool、complex(复数)
,在Python3中,只有一种整数类型int
,表示为长整型,没有python2中的Long。
示例:
1 | In [3]: aa = 1111 |
数值运算
1 | # 加法运算 |
- 注意:混合计算时,Python会把整型转换成为浮点数。
数值类型实例
int | float | complex |
---|---|---|
10 | 0.0 | 3.14j |
100 | 15.20 | 45.j |
-786 | -21.9 | 9.322e-36j |
080 | 32.3e+18 | .876j |
-0490 | -90. | -.6545+0J |
-0x260 | -32.54e100 | 3e+26J |
0x69 | 70.2E-12 | 4.53e-7j |
浮点数误差
先看一个例子:
1 | In [24]: x = 4.20 |
产生上述问题的原因,就来自于浮点数计算精度问题。
浮点数在计算机中表达为二进制(binary)小数,
例如,0.125
是1/10 + 2/100 + 5/100
的值;
又例如0.001
是0/2 + 0/4 + 1/8
的值。
这两个数值相同。唯一的实质区别是第一个写为十进制小数记法,第二个是二进制。
问题就来了,大多数十进制小数不能完全用二进制小数来表示,导致的结果是,一般情况下,你输入的十进制浮点数,由实际存储在计算机中的近似的二进制浮点数表示。
这个问题可以参见文档《浮点数算法:争议和限制》进行详细了解。
浮点数误差的解决方法
Python中的decimal模块可以解决浮点数误差的烦恼。这个模块可以通过整数、字符串、或者构建decimal.Decimal对象,来解决这个问题。如果是浮点数,因为浮点数本身存在误差,在计算前需要先将浮点数转化为字符串。
示例:
1 | In [32]: from decimal import Decimal |
- 注意,精度提升的同时,会伴随性能的损失。在对数据要求特别高的场景下,例如财务计算等,性能的损失是值得的。
String(字符串)
在Python中,字符串用单引号'
或者双引号"
括起来,如果遇到特殊字符,可以用反斜杠\
进行转义。
字符串截取的用法示例:
1 | In [41]: aa = '我爱学习' |
加号+
是字符串的连接符,星号*
表示复制当前字符串多少次:
1 | In [50]: aa + "," + bb |
我们有这样一个字符串GitOPEN\niubi
,看一下下面的操作:
1 | In [53]: cc = "GitOPEN\niubi" |
如果字符串本身有特殊字符,但是想让字符串中的特殊字符不转义,那么在字符串前面加上r
,表示按照原始字符串进行输出。
List(列表)
List可以说是Python中使用最频繁的数据类型。列表中的元素类型可以不相同,它支持数字,字符串甚至可以列表嵌套。
下面是列表,列表截取操作,列表排序操作:
1 | In [57]: a_list = ['aa', 'bb', 'cc', 'dd', 'ee'] |
Tuple(元组)
Python中,元组是用()
括起来的,元素不能修改。
1 | a_tup = ('锄禾','日','当午') |
元组内置函数
Python元组包含了以下内置函数:
序号 | 方法及描述 |
---|---|
1 | cmp(tuple1, tuple2) 比较两个元组元素。 |
2 | len(tuple) 计算元组元素个数。 |
3 | max(tuple) 返回元组中元素最大值。 |
4 | min(tuple) 返回元组中元素最小值。 |
5 | tuple(seq) 将列表转换为元组。 |
Dictionary(字典)
Python中的字典另一种可变容器模型,可以存储任意类型对象。
键值对的键和值用:
冒号分割,每个键值对用,
逗号分割;键是唯一的,值不需要唯一,如果键重复,那么最后一个键值对会覆盖前面的。
1 | In [69]: a_dict = {'a':'1', 'b':'2', 'c':'3', 'b':'4'} |
字典中键的特性
- 同一个键不允许出现两次。创建时如果同一个键被赋值两次,后一个值会被记住。
- 键必须是不可变数据类型,可以用数字、字符串、元组,但是列表就不行。
字典的内置函数
序号 | 函数及描述 |
---|---|
1 | cmp(dict1, dict2) 比较两个字典元素。 |
2 | len(dict) 计算字典元素个数,即键的总数。 |
3 | str(dict) 输出字典可打印的字符串表示。 |
4 | type(variable) 返回输入的变量类型,如果变量是字典就返回字典类型。 |
字典的内置方法
序号 | 函数及描述 |
---|---|
1 | dict.clear() 删除字典内所有元素 |
2 | dict.copy() 返回一个字典的浅复制 |
3 | dict.fromkeys(seq[, val]) 创建一个新字典,以序列 seq 中元素做字典的键,val 为字典所有键对应的初始值 |
4 | dict.get(key, default=None) 返回指定键的值,如果值不在字典中返回default值 |
5 | dict.has_key(key) 如果键在字典dict里返回true,否则返回false |
6 | dict.items() 以列表返回可遍历的(键, 值) 元组数组 |
7 | dict.keys() 以列表返回一个字典所有的键 |
8 | dict.setdefault(key, default=None) 和get() 类似, 但如果键不存在于字典中,将会添加键并将值设为default |
9 | dict.update(dict2) 把字典dict2的键/值对更新到dict里 |
10 | dict.values() 以列表返回字典中的所有值 |
11 | pop(key[,default]) 删除字典给定键 key 所对应的值,返回值为被删除的值。key值必须给出。 否则,返回default值。 |
12 | popitem() 随机返回并删除字典中的一对键和值。 |
函数
函数是组织好的,可重复使用的,用来实现单一或者相关功能的代码段。它能够提高应用的模块性,以及代码的重复利用率。我们已经使用过很多内建函数,比如print()
,但是,也可以创建用户自定义函数。
定义一个函数
定义一个函数非常简单,它有几个规则:
- 函数以
def
关键字开头,后接函数名称和():
- 传入参数和自变量必须放在
()
内 - 函数代码块的内部第一行可以使用文档字符串进行函数说明
return [表达式]
用来结束函数,选择是否返回值给调用者,不带表达式的return
相当于返回None
示例:
1 | def sayhello(text): |
参数
参数类型:
- 必备参数
- 关键字参数
- 默认参数
- 不定长参数
必备参数
必备参数必须以正确的顺序传入函数,调用的时候,数量必须和声明的一样。
1 | def printtext(text): |
关键字参数
使用关键字参数允许函数在调用时参数的顺序与声明时不一致。
1 | def printmsg(text1, text2): |
缺省参数
调用函数时,如果缺省参数的值没有传入,那么会使用默认值。
1 | def printemployee(uid, name, salary=1000.00): |
不定长参数
有的时候,我们需要一个函数,它能够处理比当初声明时更多的参数,这些参数叫做不定长参数。加了星号(*)的变量名会存放所有未命名的变量参数。
1 | def printinfo(arg1, *args): |
匿名函数
创建匿名函数的方法是使用lambda
。
示例:
1 | sum = lambda x, y: x + y |
全局变量和局部变量
定义在函数内部的是局部变量,拥有局部作用域;定义在函数外的变量是全局变量,拥有全局作用域。调用函数时,所有在函数内声明的变量名称都将被加入到作用域中。
示例:
1 | # 全局变量 |
命名空间和作用域
变量就是一个名字(标识符),它指向了对象。命名空间是一个字典,它的键是变量名称,对应的值是对象。
Python表达式可以访问局部命名空间和全局命名空间里面的变量。如果一个局部变量和一个全局变量重名,则局部变量会覆盖全局变量。
每一个函数都有自己的命名空间,类的方法的作用域的规则和一般的函数一样。Python会智能地猜测变量是局部还是全局的,并且假设在函数内赋值的变量都是局部的。
面向对象编程
Python是一门面向对象语言,因此在Python中创建类和对象是轻而易举的事情。
面向对象简介
概念 | 含义 |
---|---|
类,Class | 类是一个集合,描述了具有相同的属性和方法的对象 |
实例化 | 就是创建类的实例,类的具体对象 |
类变量 | 在实例化对象中,类变量是公用的;类变量定义在类内部并且在函数体之外 |
数据成员 | 类变量或者实例变量,用于处理类及其实例对象的相关的数据 |
继承 | 派生类继承基类(父类)的字段和方法。允许把一个派生类对象作为父类对象对待。 |
方法重写 | 子类从父类继承过来的方法,不能满足子类的需求,可以对其进行重写(override) |
方法 | 类中的函数 |
对象 | 类的实例,包括两个数据成员(类变量、实例变量)和方法 |
实例变量 | 定义在方法中的变量 |
创建类
示例:
1 | class Employee: |
count
是一个类变量,它的值在这个类的实例对象之间共享。__init__()
方法是一个特殊的方法,叫做类的构造函数或者初始化方法,当实例化该类的对象时就会调用这个方法self
代表类的实例,在定义类的方法时是必须的,但在调用时不必传入相应的参数- 类的方法与普通的函数只有一个区别,它必须有一个额外的第一个参数名称,按照习惯,它的名称是
self
1 | # 实例化对象 |
打印的结果为:
1 | 员工总数为:1 |
一些访问属性的函数:
函数 | 含义 |
---|---|
getattr(obj, name[,default]) |
访问对象的属性 |
hasattr(obj,name) |
检查是否存在一个属性 |
setattr(obj,name,value) |
设置一个属性,如果属性不存在,则创建一个新属性 |
delattr(obj,name) |
删除属性 |
内置类属性
名称 | 含义 |
---|---|
__dict__ |
类的属性,包含一个字典,由类的数据属性组成 |
__doc__ |
类的文档字符串 |
__name__ |
类名 |
__module__ |
类所在的模块,全名为__main__className |
__bases__ |
类的所有父类构成元素,包含一个由所有父类组成的元组 |
示例:
1 | print("Employee.__doc__:", Employee.__doc__) |
输出:
1 | Employee.__doc__: |
类的继承
代码重用是面向对象编程带来的主要好处之一,实现重用的方法之一就是继承机制。
示例:
1 | class Parent: |
输出:
1 | 子类构造函数 |
方法重载
如果父类的方法的功能不能满足你的需求,在子类中可以重写父类的方法。
示例:
1 | class A: |
time模块、datetime模块、json模块、csv模块使用方法
time 模块
在编写Python程序时,转换日期时间是一个常见的功能。时间间隔是以秒为单位的浮点小数。每个时间戳都以自从1970年1月1日午夜(历元)经过了多长时间来表示。
获取当前时间戳:
1 | import time |
时间元组
struct_time元组,具有如下属性:
序号 | 字段 | 属性 | 值 |
---|---|---|---|
0 | 4位年 | tm_year | 2018 |
1 | 月 | tm_mon | 1到12 |
2 | 日 | tm_mday | 1到31 |
3 | 小时 | tm_hour | 0到23 |
4 | 分钟 | tm_min | 0到59 |
5 | 秒 | tm_sec | 0到61(60或61是润秒) |
6 | 一周的第几日 | tm_wday | 0到6(0是周一) |
7 | 一年的第几日 | tm_yday | 1到366 |
8 | 夏令时 | tm_isdst | -1, 0, 1, -1是决定是否为夏令时的旗帜 |
获取当前时间
1 | import time |
输出为:
1 | 当前本地时间为:time.struct_time(tm_year=2018, tm_mon=8, tm_mday=13, tm_hour=21, tm_min=49, tm_sec=53, tm_wday=0, tm_yday=225, tm_isdst=0) |
格式化时间
1 | import time |
输出:
1 | 格式化后的时间为:Mon Aug 13 21:52:20 2018 |
格式化日期
1 | import time |
输出:
1 | 2018-08-13 21:56:49 |
datetime模块
1 | import datetime |
json模块
在使用Python进行数据处理的过程中,我们经常和json数据打交道。
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。
json模块的两个常用函数为:
函数名 | 含义 |
---|---|
json.dumps |
将Python对象编码成JSON字符串 |
json.loads |
将已编码的JSON字符串解码为Python对象 |
json.dumps
示例:
将Python对象(数组)编码为JSON格式数据:
1 | import json |
格式化输出JSON数据:
1 | data = {'name': 'GitOPEN', 'salary': 70000.01} |
python 原始类型向 json 类型的转化对照表:
Python | JSON |
---|---|
dict | object |
list, tuple | array |
str, unicode | string |
int, long, float | number |
True | true |
False | false |
None | null |
json.loads
用于解码JSON数据,返回Python字段的数据类型。
示例:
1 | import json |
csv模块
csv库可以帮助我们解决大多数CSV格式的数据读写问题。
读数据
准备一个csv格式的文件,命名为data.csv
:
1 | Uid,Name,Age,Score |
示例:将这个数据文件读取为一个元组序列:
1 | import csv |
注意:data.csv和py文件的编码格式应当统一为utf-8。
输出为:
1 | ['Uid', 'Name', 'Age', 'Score'] |
示例:将这个数据读取为一个字典:
1 | import csv |
输出:
1 | <class 'collections.OrderedDict'> |
写数据
示例:
1 | import csv |
注意:
newline=''
这个参数,你会发现,如果不加,生成的csv文件中每一行下面总是会多一行空白行。
示例:
写入字典序列数据到csv文件中。
1 | import csv |
实战──搜索引擎首页实战
写好的GitOPEN搜索首页如图所示:
整个项目的结构如图所示,项目源码位置CrawlerLessons/codes/lesson01/SearchDemo
:
index.html
源码:
1 |
|
index.css
源码:
1 | * { |
list.html
源码:
1 |
|
table.html
源码:
1 |
|
实战──简易学生管理系统
这是一个玩具代码项目,用来练习刚刚学会的Python基础知识。
这个实战例子我们不再做代码演示,请大家自行运行代码,找出代码的不足之处,写出自己的《简易学生管理系统》,要求具有的功能如下图所示:
参考代码位置:CrawlerLessons/codes/lesson01/StudentSystem
。