一 词汇训练
- 类(class):告诉python创建一个新类型的东西。(Tell python to make a new type of thing).
- 对象(object):两种含义:最基本类型的东西,任何实例。(the most basic type of thing,and any instance of something)。
- 实例(instance):当你告诉python创建一个类的时候你所得到的东西。(What you get when you tell pythong to create a class).
- def:你如何在类里面定义一个函数。(How you define a function inside a class)。
- self:在一个类的函数里面,self是被访问的实例/对象的一个变量。(inside the functions in a class,self is a variable for the instance/object being accessed)。
- 继承(inheritance):关于一个类能从另一个类那里继承它的特征的概念,很像你和你的父母。(The concept that one class can inhert traits from other class,much like you and your parents)。
- 组合(composition):关于一个类可以由其它一些类构成的概念,很像一辆车包含几个轮子。(The concept that a class can be composed of other classes as parts,much like how a car has wheels)。
- 属性(attribute):类所拥有的从组合那里得到的特性,通常是变量。(A property classes have that are from composition and are usually variables)。
- is-a:一种用来表达某物继承自一种东西的表述,就像“三文鱼是一种鱼”。(A phrase to say that something are from inherits from another,as in a "salmon" is a "fish")
- has-a:一种用来表达某物是由一些东西组成或具有某种特性的表述,就像“三文鱼有一个嘴巴。”(A phrase to say that something is composed of other things or has a trait,as in "a salmon has-a mouth.")
二 短语训练
- class X(Y) :创建一个名为 X 并继承自 Y 的类。(“Make a class named X that is-a Y.”)
- class X(object): def __init__(self, J):类 X 有一个带有 self 和 J 参数的 __init__ 函数。(“class X has-a __init__ that takes self and J parameters.”)
- class X(object): def M(self, J) :类 X 有一个带有 self 和 J 参数的 M 函数。(“class X has-a function named M that takes self and J parameters.”)
- foo = X() :设 foo 为类 X 的一个实例。(“Set foo to an instance of class X.”)
- foo.M(J) 从 foo 那里获取 M 函数,并用 self 和 J 参数来调用它。(“From foo, get the M function, and call it with parameters self, J.”)
- foo.K = Q 从 foo 那里获取 K 属性,并设它为 Q。(“From foo, get the K attribute, and set it to Q.”)
三 代码
1 urllib标准库
- 网络爬虫简介:
- 定义:按照一定规则,自动抓取万维网信息的程序或脚本。
- 两大特征:
- 能按程序员要求下载数据或者内容
- 能自动在网络上流窜(从一个网页跳转到另一个网页)
- 两大步骤:
- 下载网页
- 提取正确的信息
- 根据一定规则自动跳转其它撤销页面上执行以上两步操作
- 爬虫分类:
- 通用爬虫(常见的搜索引擎)
- 专用爬虫(聚集爬虫)
- python常用的网络包:
- Python3:urllib、requests
- urllib库:
- 是什么:urllib是python内置的处理HTTP请求的库
- 有什么:主要包含以下四个模块
- urllib.request 请求模块:它是最基本的 HTTP 请求模块,我们可以用它来模拟发送一请求,就像在浏览器里输入网址然后敲击回车一样,只需要给库方法传入 URL 还有额外的参数,就可以模拟实现这个过程了。
- urllib.error 异常处理模块:如果出现请求错误,我们可以捕获这些异常,然后进行重试或其他操作保证程序不会意外终止。
- urllib.parse url解析模块: parse 模块是一个工具模块,提供了许多 URL 处理方法,比如拆分、解析、合并等等的方法。
- urllib.robotparser robots.txt解析模块:主要是用来识别网站的 robots.txt 文件,然后判断哪些网站可以爬,哪些网站不可以爬的,其实用的比较少。
- urllib.request.urlopen函数:
- 功能:用于实现对目标url的访问。
- 函数原型:urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)
- 参数介绍:一般常用的有三个——url,data,timeout
- url 参数:目标资源在网路中的位置。可以是一个表示URL的字符串(如:https://www.boxuegu.com);也可以是一个urllib.request对象。
- data参数:data用来指明发往服务器请求中的额外的参数信息(如:在线翻译,在线答题等提交的内容),HTTP是python中实现的众多网络通信http、https、ftp等协议中,唯一一个 使用data 参数的,也就是说只有打开的是http网址的时候,自定义data参数才会有作用。
- data必须是一个字节数据对象(Python的bytes object)
- data必须符合标准the standard application/x-www-form-urlencoded format,怎么得到这种标准结构的data呢?使用urllib.parse.urlencode()将自定义的data转换成标准格式,而这个函数所能接收的参数类型是pyhon中的mapping object(键/值对,如dict) or a sequence of two-element tuples(元素是tuple的列表)。
- data也可以是一个可迭代的对象,这种情况下就需要配置response对象中的Conten-length,指明data的大小。
- data默认是None,此时以GET方式发送请求;当用户给出data参数的时候,改为POST方式发送请求。
- timeout参数:设置超时时间,单位是秒。
- 如果请求超过这个时间还没有得到响应,就会抛出异常。如果没有设定的话,就会使用全局的默认时间。支持HTTP,HTTPS,FTP!
- 我们可以设置超时时间来控制网页爬取时间超过规定时间就跳出,使用try except语句是实现。
- context参数:实现SSL加密传输。(基本上很少用)
- cafile、capath参数:是指定 CA 证书和它的路径,这个在请求 HTTPS 链接时会有用。(基本很少用)
- cadefault 参数现在已经弃用了,默认为 False。
- urlopen返回对象提供方法:
- read() , readline() ,readlines() , fileno() , close() :对HTTPResponse类型数据进行操作
- info():返回HTTPMessage对象,表示远程服务器返回的头信息
- getcode():返回Http状态码。如果是http请求,200请求成功完成;404网址未找到
- geturl():返回请求的url
- 版本区别:python2和python3在导入urlrequest的方式是不一样的。
- python2中:import urllib2
- 而python3里面把urllib分开了,分成了urlrequest和urlerror,在这里我们只需导入urlrequest即可。from urllib.request import urlopen
- Request类
- 功能:urlopen()可以实现简单的请求,但是它无法添加一些header信息,也就不能构建一个完整的请求。所以我们可以用Request类来构建一个完整的请求。
- 函数原型:class urlib.request.Request(url,data=None,headers={},origin_req_host=None,unverifiable=False,method=None)
- 参数介绍:
- url:请求的url ,必传参数。
- data: 类型是bytes类型,如果是字典,使用urllib.parse中的urlencode()编码!
- headers:参数是一个字典,表示请求的请求标识和载体!可以在构造 Request 时通过 headers 参数直接构造,也可以通过调用Request实例的add_header()方法来添加。 Request Headers 最常用的用法就是通过修改 User-Agent 来伪装浏览器,默认的 User-Agent 是 Python-urllib,我们可以通过修改它来伪装浏览器。
- origin_host:表示请求的host名称或者IP地址。
- unverifiable:参数表示这个请求是否是无法验证的,默认是False.意思就是说用户没有足够权限来选择接收这个请求的结果。例如我们请求一个 HTML 文档中的图片,但是我们没有自动抓取图像的权限,这时 unverifiable 的值就是 True。
- method:是一个字符串,它用来指示请求使用的方法,比如GET,POST,PUT等等。
- 异常处理:
- 功能:urllib 的error模块定义了由request模块产生的异常。如果出现了问题,request模块就会抛出error模块中定义的异常!
- 两个常见的异常:URLError,HTTPError,HTTPError是URLError的子类
- URLError里只有一个属性:reason,即抓异常的时候只能打印错误信息
- HTTPError里有三个属性:code,reason,headers,即抓异常的时候可以获得code,reson,headers三个信息
- code,返回 HTTP Status Code,即状态码,比如 404 网页不存在,500 服务器内部错误等等。
- reason,同父类一样,返回错误的原因。
- headers,返回 Request Headers。
- 因为 URLError 是 HTTPError 的父类,所以我们可以先选择捕获子类的错误,再去捕获父类的错误
- Url解析:
- urlparse()
- 功能:对你传入的url地址按特定的协议类型进行拆分
- 原型:urllib.parse.urlparse(urlstring, scheme='', allow_fragments=True)
- urlstring:url地址参数
- scheme:指定协议类型,如果url里面已经带了协议,再通过scheme指定的协议就不会生效
- urlunpars():用于拼接
- urljoin():也用做拼接
- urlencode():可以将字典转换为url参数
- urlparse()
- 参考内容:
2 random模块
- 功能:用于生成随机数
- 常见方法:
- random.random():生成一个随机的浮点数,范围是在0.0~1.0之间
- random.uniform(a,b) :用于生成一个指定范围内的随机符点数,两个参数其中一个是上限,一个是下限。如果a > b,则生成的随机数n: b <= n <= a。如果 a <b, 则 a <= n <= b。
- random.randint(a, b):用于生成一个指定范围内的整数。其中参数a是下限,参数b是上限,生成的随机数n: a <= n <= b
- random.randrange([start], stop[, step]):从指定范围内,按指定基数递增的集合中 获取一个随机数。
- random.choice(sequence):可以从任何序列,比如list列表中,选取一个随机的元素返回,可以用于字符串、列表、元组等。
- random.shuffle(x[, random]):原地指定seq序列,用于将一个列表中的元素打乱,即将列表内的元素随机排列。
- random.sample(sequence, k):从指定序列中随机获取指定长度的片断并随机排列。注意:sample函数不会修改原有序列。
2 代码
它所做的事情就是用一个叫做 urllib 的图书馆来下载一列单词。
1 import random # 导入random模块 2 from urllib.request import urlopen # 导入urllib库中的urlopen方法 3 import sys # 导入sys模块 4 5 WORD_URL = "http://learncodethehardway.org/words.txt" # 保存要访问的网页地址Url 6 WORDS = [] 7 8 PHRASES = { 9 "class %%%(%%%):": 10 "Make a class named %%% that is-a %%%.", 11 "class %%%(object): def __init__(self,***)": 12 "class %%% has-a __init__ that takes self and *** params.", 13 "class %%%(object): def ***(self,@@@)": 14 "class %%% has-a function *** that takes self and @@@ params.", 15 "*** = %%%()": 16 "Set *** to an instance of class %%%.", 17 "***.***(@@@)": 18 "From *** get the *** function,call it with params self @@@.", 19 "***.*** = '***'": 20 "From *** get the *** attribute and set it to '***'." 21 } # 存储类、函数、方法的定义或者调用格式 22 23 # do they want to drill phrases first 24 if len(sys.argv) == 2 and sys.argv[1] == "english": # 如果命令行参数有两个,且第二个参数是english,即在执行过程中命令行参数必须有两个,第一个是脚本文件名,第二个是english 25 PHRASE_FIRST = True # PHRASE_FIRST值为True 26 else: 27 PHRASE_FIRST = False # 否则PHRASE_FIRST值为False 28 29 # load up the words from the website 30 for word in urlopen(WORD_URL).readlines(): # 打开WORD_URL对应的网页地址,并返回有每行内容组成的列表(会保存在硬盘中),再通过for循环遍历得到的列表 31 WORDS.append(str(word.strip(),encoding="utf-8")) # 去除每行的头尾空白后,将其转换成字符串,并采用utf-8格式编码,将编码后的内容添加到列表WORDS中 32 33 def convert(snippet,phrase): # 将字典的键和值中的特殊符号和从WORDS_URL中读到的内容进行替换 34 class_names = [w.capitalize() for w in # 利用for循环遍历的到的随机列表,并将列表元素字符串中的第一个字母变大写,其它字母变小写 35 # snippet.count()表示统计PHARSES字典的键里面某个字符串出现的次数,即为伪装一个类名或其它内容需要的单词的个数 36 random.sample(WORDS,snippet.count("%%%"))] # 通过分片的方式从列表WORDS中得到长度为snippet.count("%%%")的列表,然后将分片得到的列表内部元素随机排列 37 other_names = random.sample(WORDS,snippet.count("***"))# 通过分片的方式从列表WORDS中得到长度为snippet.count("***")的列表,然后将分片得到的列表内部元素随机排列 38 results = [] 39 param_names = [] 40 41 for i in range(0,snippet.count("@@@")): 42 param_count = random.randint(1,3) # 利用random.randint()函数产生一个1、2、3中的随机整数,控制分片后列表的长度 43 param_names.append(','.join( # 用","将分片后得到的列表的内容连接成字符串 44 random.sample(WORDS,param_count))) # 利用param_count将WORDS列表分片,然后将分片得到的列表内部元素随机排列 45 46 for sentence in snippet,phrase: # 用sentence遍历PHRASES字典的键和值 47 result = sentence[:] # 利用切片操作完成对sentence列表的复制 48 49 # fake class names # 伪装类名称 50 for word in class_names: 51 result = result.replace("%%%",word,1) # 将result中的字符串"%%%"用class_names中得到的word代替,替换不超过一次 52 53 # fake other names # 伪装函数或方法等其它内容的名称 54 for word in other_names: 55 result = result.replace("***",word,1) # 将result中的字符串"***"用other_names中得到的word代替,替换不超过一次 56 57 # fake parameter lists # 伪装参数列表 58 for word in param_names: 59 result = result.replace("@@@",word,1) # 将result中的字符串"@@@"用param_names中得到的word代替,替换不超过一次 60 61 results.append(result) # 将result添加到列表results当中,并返回results列表的值 62 return results 63 64 # keep going until they hit CTRL-D 65 try: # 异常 66 while True: 67 snippets = list(PHRASES.keys()) # snippets是由PHRASES字典的键组成的列表 68 random.shuffle(snippets) # 将snippets列表中的元素顺序打乱 69 70 for snippet in snippets: # 遍历snippets列表 71 phrase = PHRASES[snippet] # 通过键snippet对应的值 72 question,answer = convert(snippet,phrase) # 调用convert函数,完成键值对中字符串的替换,并将函数返回值 73 if PHRASE_FIRST: # 74 question,answer = answer,question # 将替换后的结果与问题换过来 75 76 print(question) # 打印question,表示经过替换的PHRASES字典的键的内容 77 78 input("> ") # 可输入answer中提示的内容来查看对应的类或者方法的结构 79 print(f"ANSWER:{answer} ") # 打印answer,即question键对应的经过替换的PHRASES字典的值的内容 80 except EOFError: 81 print(" Bye")
执行过程中,输入:
1 python oop_test.py english
有关字符串的内容,可参考:https://www.cnblogs.com/luoxun/p/13257881.html