python爬虫08 | 你的第二个爬虫,要过年了,爬取豆瓣最受欢迎的250部电影慢慢看


马上就要过年啦







过年在家干啥咧


准备好被七大姑八大姨轮番「轰炸」了没?






你的内心 os 是这样的



但实际上你是这样的



应付完之后


闲暇时刻不妨看看电影


接下来咱们就来爬取豆瓣上评分最高的


250部电影


这次我们就要来使用上次说的


BeautifulSoup + Reuqests


进行爬取啦


这次


我们将爬取到的内容存放到 excel 吧



那么


接下来就是



学习 python 的正确姿势




我们还是老样子


先摸清对方的底


知己知彼


百战不殆


首先打开我们的目标链接


https://movie.douban.com/top250


可以看到这样一个网页




每一页显示了 25 条数据


当我们点击下一页的时候


链接请求参数变了


https://movie.douban.com/top250?start=25&filter=


我们一眼就看的出来


这里就是从第 25 条数据开始加载的


所以


我们可以使用这个 start=25 来做变量


实现翻页获取信息


接下来我们来看下我们要的主要信息


电影名称

电影图片

电影排名

电影评分

电影作者

电影简介





等会我们可以使用 BeautifulSoup 超简单获取


一顿分析之后


我们就开始撸代码啦



主要思路


请求豆瓣的链接获取网页源代码


然后使用 BeatifulSoup 拿到我们要的内容


最后就把数据存储到 excel 文件中


def main(page):
url = https://movie.douban.com/top250?start='+ str(page*25)+‘&filter=’
html = request_douban(url)
soup = BeautifulSoup(html, ‘lxml’)
save_to_excel(soup)


请求豆瓣电影


def request_douban(url):
try:
response = requests.get(url)
if response.status_code == 200:
return response.text
except requests.RequestException:
return None


获取到的主要源代码




<ol class=“grid_view”>
<li>
<div class=“item”>
<div class=“pic”>
<em class=“”>1</em>
<a href=https://movie.douban.com/subject/1292052/">
<img width=“100” alt=“肖申克的救赎” src=https://img3.doubanio.com/view/photo/s_ratio_poster/public/p480747492.jpg" class=“”>
</a>
</div>
<div class=“info”>
<div class=“hd”>
<a href=https://movie.douban.com/subject/1292052/" class=“”>
<span class=“title”>肖申克的救赎</span>
<span class=“title”>&nbsp;/&nbsp;The Shawshank Redemption</span>
<span class=“other”>&nbsp;/&nbsp;月黑高飞(港) / 刺激1995(台)</span>
</a>


<span class=“playable”>[可播放]</span>
</div>
<div class=“bd”>
<p class=“”>
导演: 弗兰克·德拉邦特 Frank Darabont&nbsp;&nbsp;&nbsp;主演: 蒂姆·罗宾斯 Tim Robbins /…<br>
1994&nbsp;/&nbsp;美国&nbsp;/&nbsp;犯罪 剧情
</p>


<div class=“star”>
<span class=“rating5-t”></span>
<span class=“rating_num” property=“v:average”>9.6</span>
<span property=“v:best” content=“10.0”></span>
<span>1286755人评价</span>
</div>

<p class=“quote”>
<span class=“inq”>希望让人自由。</span>
</p>
</div>
</div>
</div>
</li>


BeatifulSoup 解析


list = soup.find(class_=‘grid_view’).find_all(‘li’)

for item in list:
item_name = item.find(class_=‘title’).string
item_img = item.find(‘a’).find(‘img’).get(‘src’)
item_index = item.find(class_=‘’).string
item_score = item.find(class_=‘rating_num’).string
item_author = item.find(‘p’).text
item_intr = item.find(class_=‘inq’).string

# print(‘爬取电影:’ + item_index + ‘ | ‘ + item_name +‘ | ‘ + item_img +‘ | ‘ + item_score +‘ | ‘ + item_author +‘ | ‘ + item_intr )
print(‘爬取电影:’ + item_index + ‘ | ‘ + item_name +‘ | ‘ + item_score +‘ | ‘ + item_intr )


打印一下


爬取电影:1 | 肖申克的救赎 | 9.6 | 希望让人自由。
爬取电影:2 |
霸王别姬 | 9.6 | 风华绝代。
爬取电影:3 | 这个杀手不太冷 | 9.4 | 怪蜀黍和小萝莉不得不说的故事。
爬取电影:4 |
阿甘正传 | 9.4 | 一部美国近现代史。
爬取电影:5 | 美丽人生 | 9.5 | 最美的谎言。
爬取电影:6 |
泰坦尼克号 | 9.3 | 失去的才是永恒的。
爬取电影:7 | 千与千寻 | 9.3 | 最好的宫崎骏,最好的久石让。
爬取电影:8 |
辛德勒的名单 | 9.5 | 拯救一个人,就是拯救整个世界。
爬取电影:9 | 盗梦空间 | 9.3 | 诺兰给了我们一场无法盗取的梦。
爬取电影:10 |
机器人总动员 | 9.3 | 小瓦力,大人生。
爬取电影:11 | 忠犬八公的故事 | 9.3 | 永远都不能忘记你所爱的人。

爬取电影:21 |
无间道 | 9.1 | 香港电影史上永不过时的杰作。
爬取电影:22 | 当幸福来敲门 | 9.0 | 平民励志片。
爬取电影:23 |
疯狂动物城 | 9.2 | 迪士尼给我们营造的乌托邦就是这样,永远善良勇敢,永远出乎意料。
爬取电影:24 | 触不可及 | 9.2 | 满满温情的高雅喜剧。
爬取电影:25 |
怦然心动 | 9.0 | 真正的幸福是来自内心深处。


拿到数据啦



循环获取 10 页的所有数据


来个循环吧


for i in range(0, 10):
main(i)



获取到数据当然是要存储了


导入 excel 的库


import xlwt


创建一个 excel 的 sheet


每一列就是我们要的关键内容


book=xlwt.Workbook(encoding=‘utf-8’,style_compression=0)

sheet=book.add_sheet(‘豆瓣电影Top250’,cell_overwrite_ok=True)
sheet.write(0,0,‘名称’)
sheet.write(0,1,‘图片’)
sheet.write(0,2,‘排名’)
sheet.write(0,3,‘评分’)
sheet.write(0,4,‘作者’)
sheet.write(0,5,‘简介’)



将爬取到的所有数据写入 excel


sheet.write(n, 0, item_name)
sheet.write(n, 1, item_img)
sheet.write(n, 2, item_index)
sheet.write(n, 3, item_score)
sheet.write(n, 4, item_author)
sheet.write(n, 5, item_intr)


最后来个保存


book.save(u’豆瓣最受欢迎的250部电影.xlsx’)





运行一下吧



生成了一个 excel 文件






老规矩


小帅b把本篇涉及到的源代码放在后台了


公众号发送「250」获取



再见


近期文章


python爬虫07 | 有了 BeautifulSoup ,妈妈再也不用担心我的正则表达式了


python爬虫06 | 你的第一个爬虫,爬取当当网 Top 500 本五星好评书籍


python爬虫05 | 年轻人,不会正则表达式你睡得着觉?有点出息没有?




扫一扫

学习 Python 没烦恼




好看的人都点了


python爬虫07 | 有了 BeautifulSoup ,妈妈再也不用担心我的正则表达式了


我们上次做了


你的第一个爬虫,爬取当当网 Top 500 本五星好评书籍


有些朋友觉得


利用正则表达式去提取信息


太特么麻烦了



有没有什么别的方式


更方便过滤我们想要的内容啊


emmmm


你还别说


还真有


有一个高效的网页解析库


它的名字叫做


BeautifulSoup



那可是




是一个可以从 HTML 或 XML 文件中提取数据的 Python 库


那么这么玩呢




接下来就是


学习python的正确姿势




首先我们要安装一下这个库


pip install beautifulsoup4


beautifulsoup支持不同的解析器


比如


对 HTML 的解析


对 XML 的解析


对 HTML5 的解析


你看




一般情况下


我们用的比较多的是 lxml 解析器


我们先来使用一个例子


让你体验一下


beautifulsoup 的一些常用的方法


可流弊了呢



比如我们有这样一段 HTML 代码


html_doc = “””

<html><head><title>学习python的正确姿势</title></head>
<body>
<p class=“title”><b>小帅b的故事</b></p>

<p class=“story”>有一天,小帅b想给大家讲两个笑话
<a href=http://example.com/1" class=“sister” id=“link1”>一个笑话长</a>,
<a href=http://example.com/2" class=“sister” id=“link2”>一个笑话短</a> ,
他问大家,想听长的还是短的?</p>

<p class=“story”></p>

“””

在不使用 re 来进行正则表达式的情况下


如何快速获取到我们想要的内容呢?


先安装一下


pip install beautifulsoup4

pip install lxml


接着将 html 的源代码传给 BeautifulSoup


soup = BeautifulSoup(html_doc,’lxml’)



此时此刻


就不需要自己写正则匹配了



我们要做的就是从这个对象直接获取我们要的内容


获取标题的内容


print(soup.title.string)
#学习python的正确姿势



获取 p 标签里面的内容


print(soup.p.string)
#小帅b的故事


获取 title 的父级标签


print(soup.title.parent.name)
#head


获取超链接


print(soup.a)
#<a class=“sister” href=http://example.com/1" id=“link1”>一个笑话长</a>


获取所有超链接


print(soup.find_all(‘a’))
#[<a class=“sister” href=http://example.com/1" id=“link1”>一个笑话长</a>, <a class=“sister” href=http://example.com/2" id=“link2”>一个笑话短</a>]


获取 id 为 link2 的超链接


print(soup.find(id=“link2”))
#<a class=“sister” href=http://example.com/2" id=“link2”>一个笑话短</a>



获取网页中所有的内容


print(soup.get_text())

# 学习python的正确姿势

小帅b的故事
有一天,小帅b想给大家讲两个笑话
一个笑话长,
一个笑话短 ,
他问大家,想听长的还是短的?



除了find方法之外


如果你对css比较熟悉


也可以使用 select 方法


soup = BeautifulSoup(html_doc,‘lxml’)

print(soup.select(“title”))
print(soup.select(“body a”))
print(soup.select(“p > #link1”))



以上就是 BeautifulSoup 常用的方法


想进一步了解可以到这


https://www.crummy.com/software/BeautifulSoup/bs4/doc/


有了它


妈妈再也不用担心我的正则表达式了


下次还有人这样问你


年轻人,不会正则表达式你睡得着觉?有点出息没有?


你可以傲娇的告诉他




睡得着



本篇完


再见




近期文章


python爬虫06 | 你的第一个爬虫,爬取当当网 Top 500 本五星好评书籍


python爬虫05 | 年轻人,不会正则表达式你睡得着觉?有点出息没有?


python爬虫04 | 长江后浪推前浪,Reuqests库把urllib库拍在沙滩上



扫一扫

学习 Python 没烦恼








好看的人都点了


python爬虫06 | 你的第一个爬虫,爬取当当网 Top 500 本五星好评书籍



来啦,老弟



我们已经知道怎么使用


Requests


进行各种请求骚操作


也知道了对服务器返回的数据如何使用


正则表达式


来过滤我们想要的内容



那么接下来


我们就使用 requests 和 re 来写一个爬虫


作为一个爱看书的你(说的跟真的似的)



怎么能发现好书呢?


所以我们


爬取当当网的前 500 本好五星评书籍


怎么样?



ok


接下来就是


学习 python 的正确姿势


请在电脑的陪同下


边看本文边练习


首先我们要对我们的目标网站进行分析


先摸清对方的底


我们才能战无不胜



打开这个书籍排行榜的地址


http://bang.dangdang.com/books/fivestars/01.00.00.00.00.00-recent30-0-0-1-1


我们可以看到是这样的一个网页



每一页显示 20 本书


当我们点击下一页的时候


你可以发现地址变了


http://bang.dangdang.com/books/fivestars/01.00.00.00.00.00-recent30-0-0-1-2


也就是我们翻到第几页的时候


链接地址的最后一个参数会跟着变


那么我们等会在 python 中可以用一个变量


来实现获取不同页数的内容



接着


用我们之前说的 Chrome 骚操作


来分析一下


我们要的内容是怎么请求的


以及


返回给我们的源代码是什么样的



可以看到


我们通过 GET 请求



我们的请求头



这是服务器返回来的数据



接着我们再来分析一下我们要抓取的关键信息




我们要的就是前 500 本书的


排名

书名

图片地址

作者

推荐指数

五星评分次数

价格


通过源码我们可以看到


这些信息被放在了 <li> 标签中



那么我们等会就可以使用


年轻人,不会正则表达式你睡得着觉?有点出息没有?


来进行过滤我们要的信息


一顿分析完了之后


接下来撸代码了



主要思路


使用 page 变量来实现翻页


我们使用 requests 请求当当网


然后将返回的 HTML 进行正则解析


由于我们暂时还没学到数据库


所以解析完之后就把内容存到文件中



def main(page):
url = http://bang.dangdang.com/books/fivestars/01.00.00.00.00.00-recent30-0-0-1-' + str(page)
html = request_dandan(url)
items = parse_result(html) # 解析过滤我们想要的信息

for item in items:
write_item_to_file(item)


请求当当网


当我们请求成功之后


拿到源代码


def request_dandan(url):
try:
response = requests.get(url)
if response.status_code == 200:
return response.text
except requests.RequestException:
return None



拿到源代码了


就要对其解析


使用正则表达式获取我们想要的关键信息


获取到了之后我们封装一下数据


def parse_result(html):
pattern = re.compile(‘<li>.?list_num.?(\d+).</div>.?<img src=”(.?)”.?class=”name”.?title=”(.?)”>.?class=”star”>.?class=”tuijian”>(.?)</span>.?class=”publisher_info”>.?target=”_blank”>(.?)</a>.?class=”biaosheng”>.?<span>(.?)</span></div>.?<p><span\sclass=”price_n”>&yen;(.?)</span>.*?</li>’,re.S)
items = re.findall(pattern,html)
for item in items:
yield {
‘range’: item[0],
‘iamge’: item[1],
‘title’: item[2],
‘recommend’: item[3],
‘author’: item[4],
‘times’: item[5],
‘price’: item[6]
}



打印一下看看结果


for item in items:
print(item)


可以看到这样的数据



没毛病


现在我们获取的是第 1 页的数据


如何自动获取 25 页 500 条数据呢


来个 for 循环呗


if name == main:
for i in range(1,26):
main(i)



获取完 500 本书的数据之后


存到 book.txt 文件



def write_item_to_file(item):
print(‘开始写入数据 ====> ‘ + str(item))
with open(‘book.txt’, ‘a’, encoding=‘UTF-8’) as f:
f.write(json.dumps(item, ensure_ascii=False) + ‘\n’)
f.close()



完成


项目跑起来




打开我们存储的 book.txt 看看




前 500 本书的数据就被我们拿到啦




本篇完


完整代码小帅b已经放到公众号后台啦


需要的朋友


在公众号发送


500


即可获取


ok


咱们下回再见



扫一扫

学习 Python 没烦恼




近期文章


python爬虫03 | 那个叫做Urllib的库让我们的python假装是浏览器


python爬虫04 | 长江后浪推前浪,Requests库把urllib库拍在沙滩上


python爬虫05 | 年轻人,不会正则表达式你睡得着觉?有点出息没有?








支持小帅b的就顺手

点个好看吧


python爬虫05 | 年轻人,不会正则表达式你睡得着觉?有点出息没有?


现在


你已经会使用 python 模拟浏览器


进行一些 Http 的请求了


那么请求完之后


服务器返回给我们一堆源代码


我们可不是啥都要的啊


我们是有原则的



我们想要的东西


怎么能一股脑的啥都往自己兜里塞呢?


使不得


使不得


所以


在服务器返回给我们的源码之中


我们要过滤


拿到我们想要的就好


其它就丢一旁


那么


我们就需要学会怎么使用


正则表达式


通过它


我们才能过滤出我们想要的内容





接下来就是


学习 python 的正确姿势




真香警告


这篇文章不适合急性子的人看,要不然会把手机砸了的!但是,如果你能看完,那么正则表达式对你来说,算个 p 的难度啊?




其实


正则表达式不仅仅适用于 python


很多编程语言


很多地方都会使用到正则


试想一下


如何从下面这段字符串中快速检索所有的数字出来呢?


zui12shu234ai45der6en7sh88ixia7898os0huaib





简单来说


正则表达式就是定义一些特殊的符号


来匹配不同的字符


比如


\d


就可以代表


一个数字,等价于 0-9 的任意一个


那么你肯定想知道


其它的特殊符号表示的啥意思吧?



就不告诉你



本篇完


再见










































这是各种符号的解释



字符描述
\将下一个字符标记为一个特殊字符(File Format Escape,清单见本表)、或一个原义字符(Identity Escape,有^$()+?.[{|共计12个)、或一个向后引用(backreferences)、或一个八进制转义符。例如,“n”匹配字符“n”。“\n”匹配一个换行符。序列“\”匹配“\”而“(”则匹配“(”。
^匹配输入字符串的开始位置。如果设置了RegExp对象的Multiline属性,^也匹配“\n”或“\r”之后的位置。
$匹配输入字符串的结束位置。如果设置了RegExp对象的Multiline属性,$也匹配“\n”或“\r”之前的位置。
匹配前面的子表达式零次或多次。例如,zo能匹配“z”、“zo”以及“zoo”。等价于{0,}。
+匹配前面的子表达式一次或多次。例如,“zo+”能匹配“zo”以及“zoo”,但不能匹配“z”。+等价于{1,}。
?匹配前面的子表达式零次或一次。例如,“do(es)?”可以匹配“do”或“does”中的“do”。?等价于{0,1}。
{n}n是一个非负整数。匹配确定的n次。例如,“o{2}”不能匹配“Bob”中的“o”,但是能匹配“food”中的两个o。
{n,}n是一个非负整数。至少匹配n次。例如,“o{2,}”不能匹配“Bob”中的“o”,但能匹配“foooood”中的所有o。“o{1,}”等价于“o+”。“o{0,}”则等价于“o”。
{n,m}mn均为非负整数,其中n<=m。最少匹配n次且最多匹配m次。例如,“o{1,3}”将匹配“fooooood”中的前三个o。“o{0,1}”等价于“o?”。请注意在逗号和两个数之间不能有空格。
?非贪心量化(Non-greedy quantifiers):当该字符紧跟在任何一个其他重复修饰符(,+,?,{n},{n,},{n,m})后面时,匹配模式是贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串“oooo”,“o+?”将匹配单个“o”,而“o+”将匹配所有“o”。
.匹配除“\r”“\n”之外的任何单个字符。要匹配包括“\r”“\n”在内的任何字符,请使用像“(.|\r|\n)”的模式。
(pattern)匹配pattern并获取这一匹配的子字符串。该子字符串用于向后引用。所获取的匹配可以从产生的Matches集合得到,在VBScript中使用SubMatches集合,在JScript中则使用$0…$9属性。要匹配圆括号字符,请使用“(”或“)”。可带数量后缀。
(?:pattern)匹配pattern但不获取匹配的子字符串(shy groups),也就是说这是一个非获取匹配,不存储匹配的子字符串用于向后引用。这在使用或字符“(|)”来组合一个模式的各个部分是很有用。例如“industr(?:y|ies)”就是一个比“industry|industries”更简略的表达式。
(?=pattern)正向肯定预查(look ahead positive assert),在任何匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如,“Windows(?=95|98|NT|2000)”能匹配“Windows2000”中的“Windows”,但不能匹配“Windows3.1”中的“Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。
(?!pattern)正向否定预查(negative assert),在任何不匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如“Windows(?!95|98|NT|2000)”能匹配“Windows3.1”中的“Windows”,但不能匹配“Windows2000”中的“Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始
(?<=pattern)反向(look behind)肯定预查,与正向肯定预查类似,只是方向相反。例如,“(?<=95|98|NT|2000)Windows”能匹配“2000Windows”中的“Windows”,但不能匹配“3.1Windows”中的“Windows”。
(?<!pattern)反向否定预查,与正向否定预查类似,只是方向相反。例如“(?<!95|98|NT|2000)Windows”能匹配“3.1Windows”中的“Windows”,但不能匹配“2000Windows”中的“Windows”。
x|y没有包围在()里,其范围是整个正则表达式。例如,“z|food”能匹配“z”或“food”。“(?:z|f)ood”则匹配“zood”或“food”。
[xyz]字符集合(character class)。匹配所包含的任意一个字符。例如,“[abc]”可以匹配“plain”中的“a”。特殊字符仅有反斜线\保持特殊含义,用于转义字符。其它特殊字符如星号、加号、各种括号等均作为普通字符。脱字符^如果出现在首位则表示负值字符集合;如果出现在字符串中间就仅作为普通字符。连字符 - 如果出现在字符串中间表示字符范围描述;如果如果出现在首位(或末尾)则仅作为普通字符。右方括号应转义出现,也可以作为首位字符出现。
[^xyz]排除型字符集合(negated character classes)。匹配未列出的任意字符。例如,“[^abc]”可以匹配“plain”中的“plain”。
[a-z]字符范围。匹配指定范围内的任意字符。例如,“[a-z]”可以匹配“a”到“z”范围内的任意小写字母字符。
[^a-z]排除型的字符范围。匹配任何不在指定范围内的任意字符。例如,“[^a-z]”可以匹配任何不在“a”到“z”范围内的任意字符。
[:name:]增加命名字符类(named character class[注 1]中的字符到表达式。只能用于方括号表达式
[=elt=]增加当前locale下排序(collate)等价于字符“elt”的元素。例如,[=a=]可能会增加ä、á、à、ă、ắ、ằ、ẵ、ẳ、â、ấ、ầ、ẫ、ẩ、ǎ、å、ǻ、ä、ǟ、ã、ȧ、ǡ、ą、ā、ả、ȁ、ȃ、ạ、ặ、ậ、ḁ、ⱥ、ᶏ、ɐ、ɑ 。只能用于方括号表达式。
[.elt.]增加排序元素(collation elementelt到表达式中。这是因为某些排序元素由多个字符组成。例如,29个字母表的西班牙语, “CH”作为单个字母排在字母C之后,因此会产生如此排序“cinco, credo, chispa”。只能用于方括号表达式。
\b匹配一个单词边界,也就是指单词和空格间的位置。例如,“er\b”可以匹配“never”中的“er”,但不能匹配“verb”中的“er”。
\B匹配非单词边界。“er\B”能匹配“verb”中的“er”,但不能匹配“never”中的“er”。
\cx匹配由x指明的控制字符。x的值必须为A-Za-z之一。否则,将c视为一个原义的“c”字符。控制字符的值等于x的值最低5比特(即对3210进制的余数)。例如,\cM匹配一个Control-M或回车符。\ca等效于\u0001, \cb等效于\u0002, 等等…
\d匹配一个数字字符。等价于[0-9]。注意Unicode正则表达式会匹配全角数字字符。
\D匹配一个非数字字符。等价于[^0-9]。
\f匹配一个换页符。等价于\x0c和\cL。
\n匹配一个换行符。等价于\x0a和\cJ。
\r匹配一个回车符。等价于\x0d和\cM。
\s匹配任何空白字符,包括空格、制表符、换页符等等。等价于[ \f\n\r\t\v]。注意Unicode正则表达式会匹配全角空格符。
\S匹配任何非空白字符。等价于[^ \f\n\r\t\v]。
\t匹配一个制表符。等价于\x09和\cI。
\v匹配一个垂直制表符。等价于\x0b和\cK。
\w匹配包括下划线的任何单词字符。等价于“[A-Za-z0-9_]”。注意Unicode正则表达式会匹配中文字符。
\W匹配任何非单词字符。等价于“[^A-Za-z0-9_]”。
\xnn十六进制转义字符序列。匹配两个十六进制数字nn表示的字符。例如,“\x41”匹配“A”。“\x041”则等价于“\x04&1”。正则表达式中可以使用ASCII编码。.
\num向后引用(back-reference)一个子字符串(substring),该子字符串与正则表达式的第num个用括号围起来的捕捉群(capture group)子表达式(subexpression)匹配。其中num是从1开始的十进制正整数,其上限可能是9[注 2]、31[注 3]、99甚至无限[注 4]。例如:“(.)\1”匹配两个连续的相同字符。
\n标识一个八进制转义值或一个向后引用。如果\n之前至少n个获取的子表达式,则n为向后引用。否则,如果n为八进制数字(0-7),则n为一个八进制转义值。
\nm3位八进制数字,标识一个八进制转义值或一个向后引用。如果\nm之前至少有nm个获得子表达式,则nm为向后引用。如果\nm之前至少有n个获取,则n为一个后跟文字m的向后引用。如果前面的条件都不满足,若nm均为八进制数字(0-7),则\nm将匹配八进制转义值nm
\nml如果n为八进制数字(0-3),且m和l均为八进制数字(0-7),则匹配八进制转义值nml。
\unUnicode转义字符序列。其中n是一个用四个十六进制数字表示的Unicode字符。例如,\u00A9匹配版权符号(©)。

(来自维基百科)




你能看到这里


也是




不知道你看懵逼了没?


反正我是不想看了


接下来


才是干货



小帅b就给你精简一下


通俗的把最常用的匹配告诉你


字符描述
\d代表任意数字,就是阿拉伯数字 0-9 这些玩意。
\D大写的就是和小写的唱反调,\d 你代表的是任意数字是吧?那么我 \D 就代表不是数字的。
\w代表字母,数字,下划线。也就是 a-z、A-Z、0-9、_。
\W跟 \w 唱反调,代表不是字母,不是数字,不是下划线的。
\n代表一个换行。
\r代表一个回车。
\f代表换页。
\t代表一个 Tab 。
\s代表所有的空白字符,也就是上面这个:\n、\r、\t、\f。
\S

跟 \s 唱反调,代表所有不是空白的字符。

\A代表字符串的开始。
\Z代表字符串的结束。
^匹配字符串开始的位置。
$匹配字符创结束的位置。
.代表所有的单个字符,除了 \n \r
[…]代表在 [] 范围内的字符,比如 [a-z] 就代表 a到z的字母
[^…]跟 […] 唱反调,代表不在 [] 范围内的字符
{n}
匹配在 {n} 前面的东西,比如: o{2} 不能匹配 Bob 中的 o ,但是能匹配 food 中的两个o。
{n,m}匹配在 {n,m} 前面的东西,比如:o{1,3} 将匹配“fooooood”中的前三个o。
{n,}匹配在 {n,} 前面的东西,比如:o{2,} 不能匹配“Bob”中的“o”,但能匹配“foooood”中的所有o。
和 {0,} 一个样,匹配 前面的 0 次或多次。 比如 zo 能匹配“z”、“zo”以及“zoo”。
+和{1,} 一个样,匹配 + 前面 1 次或多次。 比如 zo+”能匹配“zo”以及“zoo”,但不能匹配“z”。
和{0,1} 一个样,匹配 ?前面 0 次或 1 次。
a|b匹配 a 或者 b。
()匹配括号里面的内容。



ok


知道了这些之后


我们怎么用 python 来进行判断呢?


那就要使用到 python 的库了


它就是


re


接下来我们就来使用 re 模块


对其常用的方法


来使用正则表达式


re.match


使用这个方法


主要传入两个参数


第一个就是我们的匹配规则


第二个就是需要被过滤的内容


例如


我们想要从这


Xiaoshuaib has 100 bananas


拿到一个数字


那么我们就可以这样


import re

content = ‘Xiaoshuaib has 100 bananas’
res = re.match(‘^Xi.(\d+)\s.s$’,content)
print(res.group(1))


通过我们刚刚说的匹配符号


可以定义出相应的匹配规则


在这里我们将我们需要的目标内容用 () 括起来


此刻我们获得结果是


0


那么如果我们想要 100 这个数字呢?


可以这样


import re

content = ‘Xiaoshuaib has 100 bananas’
res = re.match(‘^Xi.?(\d+)\s.s$’,content)
print(res.group(1))


看出区别了么


第二段代码我们多了一个 ?符号


在这里呢


涉及到两个概念


一个是


贪婪匹配


另一个是


非贪婪匹配


所谓贪婪匹配


就是我们的第一段代码


一个数一个数都要去匹配


而非贪婪呢


我们是直接把 100 给匹配出来了




刚刚我们用到的


.?


是我们在匹配过程中最常使用到的


表示的就是匹配任意字符


但是


.?的 . 代表所有的单个字符,除了 \n \r


如果我们的字符串有换行了


怎么办呢?


比如这样


content = “””Xiaoshuaib has 100 
bananas”””


那么我们就需要用到 re 的匹配模式了


说来也简单


直接用 re.S 就可以了


import re

content = “””Xiaoshuaib has 100
bananas”””
res = re.match(‘^Xi.?(\d+)\s.s$’,content,re.S)
print(res.group(1))


可能有些朋友会觉得


匹配一个东西还要写开头结尾


有点麻烦


那么就可以使用 re 的另一个方法了



re.search



它会直接去扫描字符串


然后把匹配成功的第一个结果的返回给你


import re

content = “””Xiaoshuaib has 100
bananas”””
res = re.search(‘Xi.?(\d+)\s.s’,content,re.S)
print(res.group(1))


这样子也是可以获取 100 的


但是如果我们的内容是这样的


content = “””Xiaoshuaib has 100 bananas;
Xiaoshuaib has 100 bananas;
Xiaoshuaib has 100 bananas;
Xiaoshuaib has 100 bananas;”””


想要获取所有的 100 呢?


这时候就要用到 re 的另一个方法了



re.findall


通过它我们就能轻松的获取所有匹配的内容了


import re

content = “””Xiaoshuaib has 100 bananas;
Xiaoshuaib has 100 bananas;
Xiaoshuaib has 100 bananas;
Xiaoshuaib has 100 bananas;”””
res = re.findall(‘Xi.?(\d+)\s.?s;’,content,re.S)
print(res)


这里的结果是


[‘100’, ‘100’, ‘100’, ‘100’]



又有朋友觉得


如果我们想直接替换匹配的内容呢


就比如刚刚的字符串


可不可以把 100 直接替换成 250 呢?



那就要用到 re 的另一个方法了



re.sub



可以这样


import re

content = “””Xiaoshuaib has 100 bananas;
Xiaoshuaib has 100 bananas;
Xiaoshuaib has 100 bananas;
Xiaoshuaib has 100 bananas;”””
content = re.sub(‘\d+’,‘250’,content)
print(content)


那么结果就变成了


Xiaoshuaib has 250 bananas;

Xiaoshuaib has 250 bananas;

Xiaoshuaib has 250 bananas;

Xiaoshuaib has 250 bananas;


250 个香蕉


吃….得完么??




再来说说 re 的另一个常用到的方法吧



re.compile



这个主要就是把我们的匹配符封装一下


import re

content = “Xiaoshuaib has 100 bananas”
pattern = re.compile(‘Xi.?(\d+)\s.s’,re.S)
res = re.match(pattern,content)

print(res.group(1))



其实和我们之前写的一样的


res = re.match(‘^Xi.?(\d+)\s.*s$’,content,re.S)


只不过 compile 一下


便于以后复用


好了


关于 re 模块和正则表达式就介绍完啦



知道了怎么请求数据


也知道了将返回的数据如何正则过滤


那么


爬虫对我们来说还难么?




这次本篇真的完啦



再见



扫一扫

学习 Python 没烦恼




近期文章


python爬虫03:那个叫做 Urllib 的库让我们的 python 假装是浏览器


python爬虫04|长江后浪推前浪,Requests 库把 urllib 库拍在沙滩上


对不起,我不应该出轨的!








也不知道为什么

你点了好看之后

你变得更好看了


python爬虫04 | 长江后浪推前浪,Reuqests库把urllib库拍在沙滩上


最近


有些朋友


看完小帅b的文章之后


把小帅b的表情包都偷了


还在我的微信


疯狂发表情包嘚瑟


我就呵呵了



只能说一句


盘他


还有一些朋友


看完文章不点好看


还来催更


小帅b也只能说一句


继续盘他



ok


接下来我们要来玩一个新的库


这个库的名称叫做


Requests


这个库比我们上次说的 urllib 可是要牛逼一丢丢的


毕竟 Requests 是在 urllib 的基础上搞出来的


通过它我们可以用更少的代码


模拟浏览器操作


人生苦短


接下来就是


学习 python 的正确姿势



skr


对于不是 python 的内置库


我们需要安装一下


直接使用 pip 安装


pip install requests


安装完后就可以使用了


接下来就来感受一下 requests 吧


导入 requests 模块


import requests


一行代码 Get 请求


r = requests.get(https://api.github.com/events')


一行代码 Post 请求


r = requests.post(https://httpbin.org/post', data = {‘key’:‘value’})


其它乱七八糟的 Http 请求


>>> r = requests.put(https://httpbin.org/put', data = {‘key’:‘value’})

>>> r = requests.delete(https://httpbin.org/delete')

>>> r = requests.head(https://httpbin.org/get')

>>> r = requests.options(https://httpbin.org/get')


想要携带请求参数是吧?


>>> payload = {‘key1’: ‘value1’, ‘key2’: ‘value2’}

>>> r = requests.get(https://httpbin.org/get', params=payload)


假装自己是浏览器


>>> url = https://api.github.com/some/endpoint'

>>> headers = {‘user-agent’: ‘my-app/0.0.1’}

>>> r = requests.get(url, headers=headers)


获取服务器响应文本内容


>>> import requests

>>> r = requests.get(https://api.github.com/events')

>>> r.text

u’[{“repository”:{“open_issues”:0,”url”:”https://github.com/...
>>> r.encoding

‘utf-8’


获取字节响应内容


>>> r.content

b’[{“repository”:{“open_issues”:0,”url”:”https://github.com/...


获取响应码


>>> r = requests.get(https://httpbin.org/get')

>>> r.status_code

200


获取响应头


>>> r.headers

{
‘content-encoding’: ‘gzip’,

‘transfer-encoding’: ‘chunked’,

‘connection’: ‘close’,

‘server’: ‘nginx/1.0.4’,

‘x-runtime’: ‘148ms’,

‘etag’: ‘“e1ca502697e5c9317743dc078f67693f”‘,

‘content-type’: ‘application/json’

}


获取 Json 响应内容


>>> import requests

>>> r = requests.get(https://api.github.com/events')

>>> r.json()

[{u’repository’: {u’open_issues’: 0, u’url’: ‘https://github.com/...


获取 socket 流响应内容


>>> r = requests.get(https://api.github.com/events', stream=True)

>>> r.raw

<urllib3.response.HTTPResponse object at 0x101194810>

>>> r.raw.read(10)

‘\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03’


Post请求


当你想要一个键里面添加多个值的时候


>>> payload_tuples = [(‘key1’, ‘value1’), (‘key1’, ‘value2’)]

>>> r1 = requests.post(https://httpbin.org/post', data=payload_tuples)

>>> payload_dict = {‘key1’: [‘value1’, ‘value2’]}

>>> r2 = requests.post(https://httpbin.org/post', data=payload_dict)

>>> print(r1.text)

{ “form”: { “key1”: [ “value1”, “value2” ] },}

>>> r1.text == r2.text

True


请求的时候用 json 作为参数


>>> url = https://api.github.com/some/endpoint'

>>> payload = {‘some’: ‘data’}

>>> r = requests.post(url, json=payload)


想上传文件?


>>> url = https://httpbin.org/post'

>>> files = {‘file’: open(‘report.xls’, ‘rb’)}

>>> r = requests.post(url, files=files)

>>> r.text

{ “files”: { “file”: “<censored…binary…data>” },}


获取 cookie 信息


>>> url = http://example.com/some/cookie/setting/url'

>>> r = requests.get(url)

>>> r.cookies[‘example_cookie_name’]

‘example_cookie_value’


发送 cookie 信息


>>> url = https://httpbin.org/cookies'

>>> cookies = dict(cookies_are=‘working’)

>>> r = requests.get(url, cookies=cookies)

>>> r.text

‘{“cookies”: {“cookies_are”: “working”}}’


设置超时


>>> requests.get(https://github.com/', timeout=0.001)

Traceback (most recent call last):
File “<stdin>”, line 1, in <module>requests.exceptions.Timeout: HTTPConnectionPool(host=’github.com’, port=80): Request timed out. (timeout=0.001)



除了牛逼


还能说什么呢??



扫一扫

学习 Python 没烦恼



近期文章


python爬虫入门01:教你在Chrome浏览器轻松抓包


python爬虫入门02:教你通过Fiddler进行手机抓包


python爬虫03:那个Urllib的库让我们假装是浏览器





好看的人

会有好运发生


python爬虫03:那个叫做 Urllib 的库让我们的 python 假装是浏览器


相信你已经摸清了


浏览器各种请求的套路


也知道了怎么在手机上进行请求和返回数据的抓取


那么接下来我们就开始来使用 python 了



代码 lu 起来




那么


怎么用 python 写各种请求呢?


今天要给大家介绍的就是


Urllib


这可是 python 内置的库


有了它


我们写代码就轻松了


腰也不疼了


腿也不酸了


头发也不秃了




那么怎么使用 Urllib 呢?



接下来


就是


学习 python 的正确姿势




在 Python 这个内置的 Urllib 库中


有这么 4 个模块


request


request模块是我们用的比较多的


就是用它来发起请求


所以我们重点说说这个模块


error


error模块呢,就是当我们在使用 request 模块遇到错了


就可以用它来进行异常处理


parse


parse模块就是用来解析我们的 URL 地址的,比如解析域名地址啦,URL指定的目录等


robotparser


这个用的就比较少了,它就是用来解析网站的 robot.txt


ok


了解了 urllib 之后


我们就用 python 代码来模拟请求吧



打开 pycharm


如果你还不太知道 pycharm 这个开发工具怎么玩的话


你可以看看这玩意


PyCharm使用教程:PyCharm常用技巧指南


当然


你喜欢别的编辑器也无所谓


反正我觉得


Pycharm


就是



首先我们来模拟请求百度吧


超简单


request 模块中的 urlopen 方法


首先我们导入 urllib 的请求模块


import urllib.request


我们在浏览器访问百度的时候


对于 python 来说


就是一句代码的事情


urllib.request.urlopen(http://www.baidu.com')



我们通过 request 模块的 urlopen 方法


直接用 Get 请求方式请求百度了


那么返回的内容就是和浏览器一样的


我们可以打印出来


response = urllib.request.urlopen(http://www.baidu.com')
print(response.read().decode(‘utf-8’))


我们执行



百度把源码返回给我们了





request 的 urlopen 方法


可以传入的参数主要有 3 个


urllib.request.urlopen(url, data=None, [timeout, ]*)


第一个 url 就是我们请求的链接


比如我们刚刚就请求百度


第二个参数 data


就是专门给我们 post 请求携带参数的


比如我们在登录的时候


可以把用户名密码封装成 data 传过去


在这里的 data 的值我们可以用 byte 的类型传递


第三个参数 timeout 就是设置请求超时时间


如果等好久服务器都没有给我们返回数据


我们就不鸟他了!


这就是 request 的 urlopen 主要用法。



urlopen 好像不错


但是


如果我们要欺骗服务器说我们是浏览器或者手机请求的呢?


这个时候我们需要添加请求头信息


也就是我们上次说的


request header


那么


这个时候


就该让 request 模块中的 Request 方法出场了


这个 Request 方法的参数多一些


主要的参数


urllib.request.Request(url, data=None, headers={}, method=None)


我们除了定义 url 和 data 之外


我们还可以定义请求头信息



urlopen 默认是 Get 请求


当我们传入参数它就为 Post 请求了


而 Request 可以让我们自己定义请求的方式


这样我们就可以使用 Request 来封装我们的请求信息




我们来用 Request 玩一下吧


我们来模拟登陆「逼乎」吧


https://biihu.cc/


没错


就是那个山寨知乎的网站


与世界分享你的装逼技巧与见解



进入网站进行登录


我们来抓一下数据先


通过 Fiddler 可以看到我们的请求参数



这密码不加密的



然后我们再看看我们的请求头信息



好了


知道这些之后我们就可以来模拟登录了


导入 urllib


from urllib import request,parse
import ssl


在这里我们还要导入 ssl


因为逼乎这个b用的是 https


我们可以使用 ssl 未经验证的上下文


context = ssl._create_unverified_context()


接着定义一下我们的请求 url 和 header


url = https://biihu.cc//account/ajax/login_process/'
headers = {
#假装自己是浏览器
‘User-Agent’:‘ Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36’,
}


再定义一下我们的请求参数


dict = {
‘return_url’:https://biihu.cc/',
‘user_name’:'xiaoshuaib@gmail.com,
‘password’:‘123456789’,
‘_post_type’:‘ajax’,
}


我们把请求的参数转化为 byte


data = bytes(parse.urlencode(dict),‘utf-8’)


然后我们就可以封装 request 了


req = request.Request(url,data=data,headers=headers,method=‘POST’)


最后我们进行请求


response = request.urlopen(req,context=context)
print(response.read().decode(‘utf-8’))


ok


这样我们就模拟登录了


运行一下看看


{“rsm”:{“url”:”https:\/\/biihu.cc\/home\/first_login-TRUE”},”errno”:1,”err”:null}


可以看到我们成功登录逼乎了



ok


以上就是 Urllib 的常用使用方法了


(完)


扫一扫









顺手,点个好看


python爬虫入门02:教你通过 Fiddler 进行手机抓包



哟~哟~哟~


hi起来


everybody




今天要说说怎么在我们的手机抓包


通过


python爬虫入门01:教你在Chrome浏览器轻松抓包



我们知道了 HTTP 的请求方式


以及在 Chrome 中摸清了一些套路


但是


除了对数据进行解析之外


有时候我们想


对请求的数据或者响应的数据进行篡改


怎么做呢?


我们经常在用的手机


手机里面的数据


怎么对它抓包呢?


那么…


接下来就是学习 python 的正确姿势



我们要用到一款强大免费的抓包工具


Fiddler

你可以到


https://www.telerik.com/download/fiddler


去下载


如果你觉得麻烦


没关系


小帅b已经帮大家下载好了


直接在公众号发送


抓包


就可以直接获取 Fiddler


那么 Fiddler 是怎么玩的呢?


一般情况下


我们通过浏览器来请求服务器的时候


是点对点的


我来给大家画个图


正常情况下


浏览器给服务器发送请求


服务器响应返回数据


但是这个时候


Fiddler非要来这里插一脚




然后


就变成这样了



Chrome发送请求给服务器的时候


会被 Fiddler 拦截下来


可以在这里修改请求参数什么的


然后 Fiddler 假装自己是浏览器


再发送数据给服务器



这个时候服务器接收到 Fiddler 的请求


还是天真的以为是 Chrome 发送的


于是就返回数据了


没想到在半路杀出个程咬金


返回的数据又被 Fiddler 拦截下来了



Fiddler 可以在这个时候


对数据进行修改


然后在返回给 Chrome


这就是 Fiddler 的主要使命




好了


知道了 Fiddler 的具体工作原理之后


咱们就能操作一番


安装完之后在电脑打开 Fiddler


一般情况下


我们按下 F12


就可以抓取我们在浏览器的请求了




如果这个时候你在浏览器发送请求


但是 Fiddler 没有一丁点反应


那么可以在你的浏览器配置一下代理


Fiddler 的默认代理 IP 为


127.0.0.1


端口为


8888


就拿 Chrome 浏览器为例


打开


设置–>高级–>打开代理设置


进行设置上面的 ip 地址和端口就可以了


这时候你在浏览器访问网站


在 Fiddler 就可以抓取到你的请求了



不过…


先别高兴太早


你可能会发现很多这样的错误


Tunnel to 443



因为现在很多请求都是 HTTPS


所以我们需要安装证书


才可以抓取 https 的请求


那么咋整咧?



点击菜单


Tools->Options


接着选择


HTTPS


勾上


Decrypt HTTPS traffic




勾完之后呢


有没看到右上角有个 Actions 按钮


轻轻按一下


选择


Reset All Certificates


完事之后


回到你的浏览器输入


localhost:8888


可以看到一个这样子的页面


点击 FiddlerRoot_certificate 下载证书


安装完之后再打开 Fiddler


你会发现你可以抓取 Https 的请求了



那么


各栏之间都代表啥意思呢


左边代表的就是你的请求


Result : 请求的 HTTP(s) 状态吗
Protocol : 请求协议
HOST : 请求的主机名
URL : 请求的资源目录位置
Body : 请求大小
Caching : 请求的缓存
Content-Type : 服务器响应的实体类型
Process : 是谁(进程)发送的
Comments : 备注
Custom : 自定义



当我们点击某一条请求后


在右边的 Insepector 中就可以看到具体的请求和返回信息内容了



说到这里


你会发现


这他妈的不就和上次讲的 Chrome 的开发工具面板差不多么


稍安勿躁


接下来就说说怎么来配置手机


使用 Fiddler 来抓取我们手机上的数据


在你的 Fiddler 中


像以下设置



接着


让你现在的这台电脑


和你的手机都连在同一个 wifi 下


接着


查看你电脑的 ip 地址



在你的手机上


打开你连接的 wifi


设置 http 代理服务器和端口


这里的服务器地址就是你刚找到的 IPv4 地址


端口 8888




紧接着


手机打开浏览器输入你的 IPv4 地址和端口


下载安装证书




安装完之后呢


Android手机这样一般就可以用了


iPhone的话


还要授权一下


在你手机的


设置–>通用–>关于本机–>证书信任设置–>把刚刚下载的证书打上勾




ok


搞定


你手机的所有访问都可以用Fiddler来抓包了


我现在就在我的手机上


打开微信和网易云音乐


可以看到我电脑上的 Fiddler


抓取到了!!




既然都抓到数据了


那么接下里就来点骚操作吧


使用 Fiddler 来修改一下我们的请求和返回数据


应该很好玩!


我们来玩玩 b 站吧


手机打开bilibili




这时候我们可以在 Fiddler 设置过滤


我们就针对 b 站的请求



然后我们在 Fiddler 按一下


ALT+F11


按完之后呢


所有服务器的返回都会被 Fiddler 拦截


ok


接下来


比如我要看 b 站的热门内容


那么我们点击这个 热门 的tab




可以看到


Fiddler 拦截了



我们点击这个请求


然后点击右边的 Inspectors


这时候可以看到 b 站服务器给我们返回了热门内容


也就是在这个时候


我们来篡改一下这些数据


让我们改的数据显示到手机上


那就把第一个视频的标题改了吧


改成


小帅b太帅了!!




改完之后呢



我们点击 Run to Completion


也就是将我们的数据发给手机


那么这个时候


看看我们的手机吧




oh


不好意思


小帅b成为b站热门第一了!


哈哈哈



ok


以上我们演示的是返回数据的拦截


那么对于请求时的拦截


快捷键是 F11


相信你也知道怎么玩了!


(完)




快来加入 Pythonner 的聚集地









python3入门基础有趣的教程

pick up Python

给大家说一下,我要开始学习 Python 了, Python 最近很火嘛(小样,别太膨胀),不过还好我是个程序员,只不过之前玩的不是 Python 语言,所以接下来我要 pick up Python了。是的,没错,pick up,以后你告诉别人说你要学 python,你可以很装逼的告诉他:“老子要pick up Python了!”

人生苦短,我特么要pick up Python~~~

而这里呢,和其它的学习 Python 的号不一样,不会乱七八糟,我会形成一个体系,也就是 Python 从0到1的整个体系,而且我也不想严肃,我要让我的这个教程呢,看起来好笑,好笑之中又能真正的学到Python的精髓,所以我会下功夫去学习,去消化,然后再转化成风趣幽默的文章,让大家看起来像看小黄文一样轻松,这是我想做的事情。

听到小黄文,想想还有点鸡动呢 (你可别乱来啊!)

为什么要学 Python

对了,还没告诉你为什么要学 Python 呢,我来说说这几点就已经足够:

Python

  1. 现在 Python 已经成为世界上最流行的编程语言之一了,而且大部分的Linux系统,MacOS系统都直接内置了 Python ,就问你牛逼不?
  1. 现在连小学生都开始学习 Python 了,Python 已经纳入了某地区小学的教材了。Pyhon 已然成为了编程界的 “网红”,现在程序员们可能不知道Cobol,Basic,Pascal,Perl,Ruby,但没有一个程序员不知道Python的。
  1. 上手简单,现在很多从来没接触过编程的人都着手开始学习Python 了,我有一朋友,之前没有任何编程基础,学了半年多找到了份工作,工资12k妥妥的,不过不要去羡慕别人的数字,人家背后的努力你没看到而已,如果你现在也是没有任何基础或者想要从0学习 Python ,那么你来对地方了!因为人生苦短,我们一起搞 Python。
  1. web开发,科学计算,3D建模,人工智能,嵌入式开发,云计算,大数据等等都特么能看到Python的身影,不知道你知不知道NASA(美国宇航局)使用Python来开发用于系统集成和卫星,火箭的测试自动化么?还有网易,腾讯,搜狐,金山,豆瓣,YouTube ,google,雅虎(太多,举例不完)都在用Python。所以这么牛逼,何不 pick up python 呢?
  1. 用 Python 可以做很多事情,可以爬取你想要的数据,可以做外挂,之前的微信跳一跳,12306抢票等都可以用Python实现,还有很多数据分析,项目系统,聊天系统,游戏等等多了去了。所以这么牛逼,何不 pick up Python 呢?

是不是真的啊?又想骗我学习~

不妨再来看下Python官网的介绍,他说这些是使用Python的人宁愿不使用其他任何东西的一些原因

python

  1. Pyhon很牛逼…而且很快;

  2. 可以和别人一起P;

  3. 在哪都可以搞;

  4. 非常友好&学习简单;

  5. 开放。

好棒!我要pick up Python了,接下来将是学习python的正确势!

别怕,Python 不是蟒蛇

PS:虽然 Python 的中文意思是「蟒蛇」,但是 Python 语言的创造者 Guido van Rossum 是因为超喜欢英国广播公司的节目「蟒蛇飞行马戏」而命名这个语言的,所以你可别以为Python 创造者是个喜欢蟒蛇的怪叔叔。

python 创始人

Python : Hello World !

不管学什么编程语言,在一开始入门的时候,都会从「Hello Wrold」开始,这已经成为编程界的不成文规定。

在1972年的时候,有个叫科比 布莱恩的人使用B语言撰写了第一个使用参数的 Hello World 相关程序。说明一下:此科比非彼科比,这哥们当然不是我的那位打NBA的偶像啊!

如果科比不打NBA而去编程,会是怎么样呢?

科比:你们给我悠着点!!

看下图!这就是由 科比 布莱恩 撰写的「Hello Wrold」程序:

Hello Wrold

自此,Hello World 成为了计算机程序员学习新的编程语言的传统美德!

当然说到传统美德,尊老爱幼也是必须的。其实我现在发现大多数年轻人素质都比较高,反而是那些年长的老人,倚老卖老,所以以后问路尽量找年轻人。

那么,我们学习 Python 也从「Hello World」开始吧!

安装 Python

如果你用的 Mac 或者 Linux 的话,那么你就不需要安装了,因为系统已经内置 Python 了,如果是 Windows 系统的话,安装也很简单,比安装 LOL 英雄联盟还简单。所以我相信不用我说,你也知道怎么安装,如果你连软件都不会安装,那么可以不用关注我了。

说的好屌啊,不知道是不是真的?

你可以直接访问 Python 的官网 下载最新的版本。

下载 python

在这里告诉一下完全没经验的朋友们,千万不要去百度搜索 python 下载,然后去到类似这样的地方下载:

别在这里下载 python

因为这样做很容易被人骂傻逼的

听说现在骂百度是一种正确的价值观!

开始玩耍

已经安装好Python之后呢,你可以在命令行里面输入「python」,然后你就会看到这样的东东:

python 版本

有没有看到三道杠杠 「 >>>」。是不是突然想到小学的时候,那些受老师爱戴,学生中的好榜样的队长袖口上的三道杠!

三道杠,怕不怕

大队长和大队委,牛逼牛逼,社会社会。

不过在 Python 这里呢, >>> 是一个提示符来的,也就是在它后面可以输入一些内容,更确切的说,这是交互式Pyhon解释器接收内容的符号

比如我们要 Python 给我们打印 Hello World 的字样,那么你就可以这样子:在 “三道杠” 后面输入 print (“Hello World”) , 然后用力按一下回车键,你就可以看到 Python 解释器打印出 Hello World 这样的字符串了:

Hello World

当然仅仅是打印 Hello World 你可能觉得没什么牛逼的,但是这不是才入门么,想要做更多有趣的事情么?跟着我一步一步来!

Pythoner :挑选一个Python编辑器

各位 Pythoner 好啊!在这个烦躁的时代,相聚就是缘分,很高兴各位 Pythoner 能相聚于此,希望接下来的路,我们一起走下去,使用 Python 来做一些有趣的事情,有意义的事情。

我们在玩游戏的时候,我们通过层层努力的打怪升级,为的是什么?是女人么?是金钱么? 当然不是,我们有那么肤浅么?我们为了能够拥有更牛逼的装备。

老话说的好:工欲善其事必先利其器!你的武器越牛逼,你的女人就越能够对你服服帖帖的。

所以,我们在使用 Python 来编程的时候,我们也需要一个牛逼的武器,来编写我们的代码 —— 编辑器!

在这里跟大家说一下现在市面上比较主流的 Python 编辑器供你参考,要知道,适合自己的才是好的。如果你的丁丁很小,使用再大 size 的套套也是白搭!

Sublime Text

Sublime Text

Sublime Text 比较适合 Python 新手使用,Sublime Text支持跨平台,而且可以使用其丰富的插件和主题。各种语法高亮和代码补全,整体看起来挺舒服的,而且主题配置起来也不难。

IDLE

IDLE

如果你是 Windows 系统可以使用 IDLE, 它是 Pyhton 自带的一款编辑器,所以刚开始也可以使用它来玩玩,IDLE具备语法高亮功能,还允许你在IDLE中运行你的程序。许多事情它会自动帮你处理。比如debug什么的。

VIM

VIM

Vim是一款强大的编辑器,如果你熟练使用 Vim 的话,那么你完全可以脱离鼠标,双手在键盘上像弹钢琴那般酸爽,不过 Vim 需要一定的学习成本,需要花点时间去研究一下各种快捷命令和插件的使用,但是从长远来看,这都是大有所益的。

PyCharm

PyCharm

我个人比较中意这个,如果你使用过 IntelliJ IDEA 的话,你应该会对其爱不释手,而这款 PyCharm 也是出自同一家公司,用起来会很顺手,现在很多公司,如Twitter,Groupon,Spotify,eBay和Telefonica等都在用 PyCharm 。不过你使用它的专业版需要花钱购买。

Emacs

Emacs

Emacs 在 python 开发界也很受欢迎,它是一款开源的编辑器,支持插件扩展,可以配置一个 python 集成开发环境, Emacs 不仅仅是一个编辑器,他是一个整合环境,可以说是一个集成开发环境。

ok,就推荐这几个市面上比较流行的编辑器,当然还有其他的编辑器,最适合自己的才是最好的,用起来顺手不尴尬才爽嘛~

在这里给点建议就是新手可以先上手使用 IDLE 和 Sublime Text ,Vim是一款强大的编辑器,没事花点时间研究下,相信我,真的会受益匪浅的。

自己写一个 Say Hello 的 python 程序

是不是觉得我特么才安装了 Python 软件,这么快我就可以写出 python 程序了?

先别怀疑着先,一开始我就说了,Python语言简单,上手快,所以你跟着我呢,一步一步来,准没错的。

又他妈的不要脸了!

通过 Pythoner :挑选一个Python编辑器相信你已经知道使用什么样的编辑器了,因为这里力求从0到1,做一个完整 python 的体系,所以现在就先用 IDLE 这个编辑器,到时候你越来越牛逼了,咱们再换编辑器,没毛病。

好了,别废话了,快点带我写程序啊!

这个Python程序可以干嘛

首先我们来想一下我们这个 Python 程序可以干嘛?

  1. 可以让我们输入名字;
  2. 可以跟我们输入的这个名字say Hello!

ok,我们要达到以上的功能,咱们说干就干!

开始编写第一个python小程序

打开我们的编辑器:

IDLE编辑器

现在的它是处于交互式解释器的状态,如果我们现在在这个交互解释器编写代码,那等下关掉所有的代码就不见了,我们当然是想要能够写出一个自己和别人都能够运行的程序,怎么能说代码丢掉就丢掉呢?

我的小九九都被你发现了,是不是我的pp一抬,你就知道我是要拉尿还是拉shit。

那么我们就使用快捷键「Ctrl + N」来新建一个编辑窗口,可以看到这里没有「三道杠」提示符了吧,我们在这里写的代码待会可以保存,爱在哪里运行就哪里运行。

IDLE编辑器

我们刚刚说了,想要这个程序可以让我们输入名字,那么我们可以用一个叫做 name 的变量来接收别人输入名字,可能你现在不知道变量是什么鬼,但是没关系,你现在把它理解为是一个桶,这个桶可以来存放用户输入的名字就好了,往后我会告诉你变量的使用,别急,咱们慢慢来。

ok,那么我们就可以写我们的第一行代码了:

1
name = input ("你他妈叫什么玩意儿?")

解释一下这行代码的意思,input 是输入的意思,而「你他妈叫什么玩意儿?」就是显示给用户看的提示语。

我们已经完成了第一点,也就是这个程序可以让我们输入名字,那么我们继续完成第二点,可以跟我们输入的这个名字say Hello!

那么很简单,我们只要再写一行代码即可:

1
print("Hello" + name)

解释一下这行代码的意思, print 就是打印的意思,你可以理解为信息的输出,我们已经知道 name 这个 “桶” 已经装了用户输入的名字,所以 “Hello” + name 就是会输出 Hello xxx!

IDLE编辑器

ok,我们已经写完代码了,我们「Ctrl + S」保存一下文件到桌面,你可以把它命名为「Hello.py」。

接着我们就可以来运行我们的程序了,在我们的 IDLE 中用力的按一下 F5 开始运行程序:

IDLE编辑器

可以可以~

看到木有,我们的程序完成了。是不是挺好玩的!慢慢来,我们到时就可以写游戏,写网站,写爬虫了,是不是想想还有点小激动呢?

什么是常量,什么是变量?

这两个概念很简单理解,以后我们在使用 Python 编程的时候也会经常用到。

常量

我们知道,世界杯踢球每队会派出 11 名队员出场比赛,这里的 11 是固定不变的。我们高中的时候学的物理有个叫做重力加速度的概念,它是 9.8 m/s²,这里的 9.8 也是一样是固定不变的,对于这些固定不变的,具备字面上的意义的量我们就称为「常量」,它就像一座高高的大山,不会被轻而易举的改变,愚公移山?不存在的。

愚公移山

愚公不畏艰难,坚持不懈,挖山不止,最终感动天帝而将山挪走的故事。通过愚公的坚持不懈与智叟的胆小怯懦,以及“愚”与“智”的对比告诉人们,无论遇到什么困难,只要有恒心、有毅力地做下去,就有可能成功。

这特么跟常量有毛关系?

变量

自己动手写一个会跟你 Say Hello 的 python 程序中我们就谈到了变量这个玩意,我说变量可以把它理解为一个「桶」,你可以通过它来存储一些变化的值。

其实说白了变量只是你的计算机中存储信息的一部分内存,它可以存储所有可以变化的值。

比如说你想要用「 i 」 来表示一个变量,对python来说是一件很简单的事,你只要用 「i = 变化的值」就可以了。

举个例子:

python 变量

这里使用 i 来表示一个变化的值 5,也就是说我们将 5 赋值给变量 i 。那么现在这个 i 指向的值就是 5 。

所以这里的 i+6 就是 5+6。

假如我们现在想让 i 来表示的值变成 2,这完全没问题,只要这样即可:

python 变量

男人能屈能伸,可长可短,算不算变量?

注意了,Python中的变量名称只能由字母、数字、下划线构成,而且不可以数字打头,像「xiaoshuaib_520」这样的是合法的,但是如果是「520_xiaoshuaib」那是不可以的。

不信你瞧:

python 变量

Python基本数据类型之「数」

相信通过什么是常量,什么是变量?你已经知道了变量是个什么玩意了,变量可以来处理变化的值,而这些变化的值呢,是可以对其分门别类的,也就是说每个变化的值它是有专属的类型的,你可以理解为这个值打一个标签。

在这里补充一点:Python 中的变量是不需要声明。每个变量在使用前都必须赋值,变量赋值以后这个变量才会被创建。

比如说 i = 5 ,在这里并不需要去定义这个 i 的类型,例如「整数类型 i = 5」,我们只要直接把 5 赋值给 i 就可以了,赋值后这个变量 i 就被创建了。这时候我们就可以说变量 i 现在所指的是一个为「整数类型的值5」。

Python除了基本数据类型「数」之外,还别的基本类型例如字符串,我们也可以自己定义数据类型,这个往后讲。

接下来就来说说 Python 中基础数据类型中的「数」。

在 Python 中的数有四种,分别是整数(int)、长整数(long)、浮点数(float)、复数(complex)。

整数

像 6 这样的数字就是整数,不带小数点的,而长整数只不过代表的是比较大一点的整数,现在 python3 中的整数(int)已经不限制数的大小限制了,所以整数类型也包括长整数。

我们可以通过 Python 交互式解释器来运算整数:

python运算整数

这里的 「6+6」没什么好说的吧,而 「6//2」就是6整除2的意思了,「1%2」的意思是说1除以2的余数,「%」有个专业名词叫做取余或者取模。而「2**3」就是2的三次方的意思。

怎么样?简单吧!

浮点数

但是如果你试试 「1/2」,这时候你会发现结果有小数点:

python运算浮点数

在这里的 「/」是除的意思,但是不会整除,你可以看到每次的结果都会有小数点。而这些像 「0.5」,「1.0」带有小数点的数我们就叫做浮点数。

复数

Python中的复数由实数部分和虚数部分组成。虚部的后缀为「j」。

例如:4+5j 就是一个复数,实数部分为 4.0,虚数部分为 5.0。

你可以把复数理解成为一个平面的一个点,例如上面这个例子你可以把它理解为平面上的点(4,5)。

Python连复数都支持,你说它能不强大么?

二进制八进制十六进制的快速转化

二进制

我们都知道,在计算机中,存储的数据都是像这样「010101010110010101…」的东东,这一串数字就是二进制。

想想你家里的灯,是不是只有两种状态,一种是开灯,一种是关灯。

开关灯

而我们的计算机在表示数据的时候也是按照这样的状态来表示的。也就是一开一关两个状态。

我们把 0 当做关,把 1 当做开!

0有点像把锁,1有点像把钥匙!emmmm..

但是现在想想啊,我们那么多数据,比如说一个 mp3 音乐,一部苍老师的教程视频,如果只让计算机仅仅以 0 和 1 这两种状态来表达这些数据,那是心有余而力不足的。

那么怎么办呢?这时候国际标准化组织就决定了,不够用是吧,那么用 8 个这样的状态来表达一个数据!

也就是:

一个数据 = 01010101 (8个状态)

那么这样的由8个状态组成的数据就叫做字节

不信的话你可以随便点开的桌面的文件,右键打开属性看看,是不是都会给你显示这个文件的大小都会用字节来表示:

文件的大小

你这小黄图能否图片分享一下?

所以知道以下的东东代表的是什么了吧:

1byte(字节)= 8bit(位,状态)

1kb = 1024byte
1mb = 1024kb
1g = 1024mb
1tb = 1024g

二进制怎么转化成八进制?

我们已经知道了一个字节需要8个二进制位来表示,有点长了,那么用八进制来表示的话就会短一点,比如说有怎么一个字节:

0101101

如果我们想把它变成 八进制 的话,那就从右到左,每三位当做一个,最左边的不够就补0。也就是说上面这个可以这样:

000101101

把每三位的整体转化成十进制的数,就变成八进制了。至于怎么转换,下面会说到。这时候用八进制就只用3个数就可以表示了。

二进制怎么转化成十六进制?

同理,十六进制可以用更少的位数来表示,如果我们想把0101101变成 十六进制 的话,那就从右到左,每四位当做一个,最左边的不够就补0。也就是说上面这个可以这样:

00101101

把每四位的整体转化成十进制的数,就变成十六进制了。至于这么转换,下面也会说到。这时候用十六进制就只用2个数就可以表示了。

不同的进制表达方式

二进制是由 「0,1」 组成,通常以 0b 开头。

八进制是由 「0,1,2,3,4,5,6,7」 组成,以 0 开头。

十进制是由 「0,1,2,3,4,5,6,7,8,9,0」 组成。

十六进制是由 「0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f」 组成,以0x开头的。

进制之间的相互转化

在这里告诉大家一个进制之间快速转化的方法,当然,不是使用计算器啊 - -

首先你只要记住以下对应关系即可:

1
2
3
1    1    1    1    1    1    1    1

128 64 32 16 8 4 2 1

二进制转化为十进制

那么如果告诉你一个二进制 如 0b11111111,转化成十进制,怎么做呢?把对应的数加起来就可以了。

0b11111111 = 128+64+32+16+8+4+2+1 = 255

看到 255 有没有一种熟悉的感觉?

所以这时候再给你出道题,把 0b010110 转化成十进制你应该会了吧?

0b010110 = 16 + 4 + 2 = 22

十进制转化为二进制

同样的:

1
2
3
1    1    1    1    1    1    1    1

128 64 32 16 8 4 2 1

我们要把十进制如22,转为二进制就是:

22之内16有没有? 那么在16对应的地方就有1。

22-16=6,那么8对应的就不存在了。

6之内有4对吧,那么4对应的就有1,6-4=2,那么2也有,2-2=0,所以1就没了。

所以最后的答案就是 22 = 0b10110。

二进制转化为八进制

我们已经知道了在二进制中每三位的十进制代表一个八进制位:

000101101

那么这时候只要把这个二进制拆成三份,每一份转化成十进制,再组合起来就是八进制了。

000 = 0;

101 = 4+1 = 5;

101 = 4+1 = 5;

所以二进制 0b000101101 = 八进制0055。

二进制转化为十六进制

我们已经知道了在二进制中每四位的十进制代表一个十六进制位:

00101101

那么这时候只要把这个二进制拆成两份,每一份转化成十进制,再组合起来就是十六进制了。

0010 = 2;

1101 = 8+4+1 = D;

所以二进制 0b00101101 = 十六进制0x2D。

ok,以上,其实说实话,如果不懂这个也不影响后面使用 Python 来编程,但是懂的多一些总归没有什么坏处。

各种符号的意义及用法

我们小时候,老师都教过我们 1+1=2 ,这个 「1+1」 就是表达式, 「+」 就是运算符。

咱们接下来就来了解一下,在 python 中,那些运算符是什么意思,怎么用? 相信看完,你就能够明白了。

加减乘除(+-/*)

对于 +-*/ 我们都知道它们是什么含义了吧,就算你的数学是体育老师教的,你也会懂加减乘除吧。

不过有两个小细节值得你去注意,就是字符串之间的相加和相乘:

python运算浮点数

看懂是啥意思了么?

字符串之间的相加会被”拼接”起来,而字符串和数字相乘就会重复多次相同的字符串。

其它的大于、小于、大于等于、小于等于就不说了,因为我们小学老师都跟我们说过了。接下来说几个比较少见的符号。

幂(**)

幂就是以前我们学数学的时候老师讲的什么什么几次方,别一看到幂就想到杨幂。

杨幂

用符号 ** 表示, 比如 2**3 = 8

整除(//)

我们知道 / 是除的意思,你知道 6/3 等于多少么?你可能会觉得在侮辱你的智商对不对,不是 2 么? 在 python 中得出的结果是 2.0 , 也就是它返回的是浮点数。 那么我们只想得到整数部分怎么玩呢?

用 // 这个 : 6//3 = 2。

取模(%)

取模的意思不是让你去获取个模特,是得到除法的余数,比如 8%5 = 3 ,因为 8/5 = 1余3。

左移(<<)和右移(>>)

移的意思就是把一个数的二进制移动多少个位。

比如 2 << 2 = 8 。这是为什么呢?

首先 2 的 二进制 是 0b00000010 ,然后将它左移2位(虚位补0)就变成这样: 0b00001000 ,它对应的十进制就是 8 。

同样的道理:

8 >> 2 的意思就是将 8 的二进制向右移动2位:

0b00001000 右移动2位:0b00000010 也就是对应十进制的 2。

那么下次有人问你2*8怎么样写代码比较高效,你就直接甩给它: 2<<3 就好了。

与(&)

记住一句话:”同真与真”,什么意思呢? 比如 1&1=1,1&0=0,

1就是真,0就是假。也就是只有 1&1=1,其它的都等于0。

那么 2 & 3 怎么算?

先将它们转化为二进制:

2对应的二进制 : 0b00000010

3对应的二进制 : 0b00000011

那么从右往左: 0&1=0 ,1&1=1,0&0=0,所以结果为

0b00000010,转化为十进制就是2,所以 2&3=2。

或(|)

记住一句话:”同假或假”,什么意思呢? 比如 1|1=1,0|0=0,

1就是真,0就是假。也就是只有 0|0=0,其它的都等于1。

那么 2 | 3 怎么算?

先将它们转化为二进制:

2对应的二进制 : 0b00000010

3对应的二进制 : 0b00000011

那么从右往左: 0|1=1 ,1&1=1,0&0=0,所以结果为

0b00000011,转化为十进制就是3,所以 2|3=3。

异或(^)

相同者假,不同者真,什么意思呢?就是 1^1=0, 1^0=1。

那么 2^3 怎么算?

先将它们转化为二进制:

2对应的二进制 : 0b00000010

3对应的二进制 : 0b00000011

那么从右往左: 0^1=1 ,1^1=0,0&0=0,所以结果为

0b00000001,转化为十进制就是1,所以 2^3=1。

翻转(~)

x的按位翻转就是是-(x+1)。

那么 ~2 怎么算?

~2 = -(2+1) ; 所以答案就是-3。

ok,以上,其实没必要去记住,了解一下就这些符号是什么意思,怎么算的就好了。

Python基本数据类型之「字符串」

单引号(’)字符串

把一段文本用单引号「’」包围起来,它就变成了字符串,和数一样是一个值。比如:

text = ‘世界上最帅的人是wistbean’

这里的变量名就是text,而对应的值就是字符串「世界上最帅的人是wistbean」。

双引号(“)字符串

把一段文本用双引号「”」包围起来,它就变成了字符串,和数一样是一个值。比如:

text = “世界上最帅的人是wistbean”

这里的变量名就是text,而对应的值就是字符串「世界上最帅的人是wistbean」。

挖槽,这不是和单引号一样么?别特么逗我啊!

哈哈,是的,其实单引号的字符串和双引号的字符串是一样的,不过为什么Python要支持单引号又支持双引号呢?

那是因为,有时候我们的文本里面,不一定就只用双引号或者单引号啊,比如说:

“包钟480,包夜1200”,她说。

这句话对于 Python 解释器来说,他只认识引号里面的内容,也就是说 python 只知道字符串「包钟480,包夜1200」,而后面的「,她说。」对于 Python 来说不认识。

那么如果是这样的话:

‘“包钟480,包夜1200”,她说。’

Python 就能懂!

所以你应该理解为什么 Python 同时支持双引号和单引号了吧。

包夜太贵了,能不能便宜点啊?

三引号字符串(’’’或者”””)

这三引号是来干嘛的呢?如果你要表示一个很长很长的字符串,那么这个三引号就可以派上用场了,因为它支持跨多行,而且在这个三引号的字符串里面你要用单引号和双引号都无所谓。

像这样:

“”” MM:”噢,请你不要吻我”MM:”噢,请你不要吻”MM:”噢,请你不要”MM:”噢,请你不”MM:”噢,请你”MM:”噢,请”MM:”噢” “””

Python 是完全看得懂的。

我好像发现了什么不得了的事情!!!

转义

可能你会对这样的字符串「’”包钟480,包夜1200”,她说。’」感到别扭,老子就想都用一种引号,不想要一下双引号一下单引号的行不行?

行行行,老子说什么就是什么!

那么这时候就可以用「转义」来解决,转义的符号是反斜杠「\」。

比如这句话「’”包钟480,包夜1200”,她说。’」我们通过转义可以变成这样:

‘ \’包钟480,包夜1200\’,她说。’

那么这个时候 Python 就能够看懂了, 现在这玩意「\’」在 Python 眼中就是「’」。

所以你可以把转义「\」理解为是为了让 Python 看的到我们想要表达的东西。

字符串的拼接

有时候我们需要两段话拼接在一起,对于 Python 来说so easy,只要像两个数字一样相加即可。

像这样:

x = "Hello, "

y = "World!"

x+y

这时候呢,「+」这个符号就把两个字符串连接起来了,在这里的 x+y 就等于 Hello,World!

原始字符串

有一些符号是代表特殊意义的,比如说 「\n」就代表换行。比如像这样:

print(“小帅b\n我爱死你了。”)

那么这时候在 Python 眼中就是:

小帅b

我爱死你了。

这很好啊, Python 很聪明还帮忙换行啦!

可是,有时候 Python 自作聪明了,比如说我们有这么一个在 c 盘下的一个叫做niubi的文件夹「C:\niubi」,那么我们这样打印的话:

print(“C:\niubi”)

结果你也知道了,路径被拆掉了。

这就尴尬了,不过还好,有个叫做原始字符串的东西,我们只要在前面加个「r」就相安无事了,这时候 Python 就知道,哦,原来你要的是原始字符串啊,那老子不帮你换行了,省的被说自作聪明。

我们只需要这样:

print(r”C:\niubi”)

ok,Python基本数据类型之「字符串」就到这里,当然字符串的使用以后会经常用到的,对字符串的操作,字符串的序列,Unicode等是接下来需要了解使用的。

Python 的控制流条件语句

if…else

还记的你以前小学的时候老师问你用「如果…那么…否则…」来造句么?每当想起这个的时候,我就会想到费玉清老师的经典名句:

「你追我,如果你追到我,我就跟你嘿嘿嘿。」

那么在Python如何表示的呢? 其实很简单,就是 if 和 else:

1
2
3
4
5
6
7
8

if 你追到我: (如果的条件语句)

我就跟你嘿嘿嘿 (如果为真,就执行这里)

else : (否则)

我就不跟你嘿嘿嘿 (如果为假,就执行这里)

if…elif…else

此外,如果老师要你用「如果…否则如果..否则..」来造句的话,比如说:如果你很持久,那么我嫁给你,否则如果你很有钱,那么我考虑一下,否则滚蛋。那么对应于 python 来说就是:

1
2
3
4
5
6
7
8
9
10
11
12

if 你很持久:

嫁给你

elif 你很有钱:

考虑一下

else

滚蛋。

好了,我们已经知道怎么用Python去使用我们的条件语句了,那么如果你想开发一个猜数字的小程序对你来说不在话下了。

我们这就来开发一个python猜数字小游戏,首先我们自己在程序定义好一个数字,然后让用户去猜,如果猜中了我们就恭喜他,猜不中就告诉他猜的数字偏大还是偏小。

打开我们的idle,撸起我们的代码:

首先定义一个变量,把我们要被猜的数字先写好:

number = 520

接着让用户输入数字:

guessNumber = int(input('请输入你要猜的数字: '))

接着我们来判断:

1
2
3
4
5
6
7
8
9
10
11
12

if guessNumber == number :

print("哇塞,牛逼啊,这就被你猜中了")

elif guessNumber < number :

print("你猜的数字小了,再往高了猜")

else :

print("你猜的数字大了,再往低了猜")


and

如果你想要一个又有钱又帅的男人,怎么用 python 表示呢?

可以这样:

1
2
3
if 有钱 and 帅 :

嫁给你。

在这里就用到了「and」这个逻辑符,就是并且的意思,如果有钱和帅同时成立,那么就执行 if 下的语句。如果他没钱,那么立即返回,不会再管他帅不帅了,不会去执行 if 下面的语句。

or

那么这时候你可能会问:那么我想要嫁给一个有钱或者帅就行了,也就是满足其一我都嫁,怎么表示呢?

可以这样:

1
2
3
if 有钱 or 帅 :

嫁给你。

这里用到的「or」逻辑符,它代表的意思就是或者,如果他是一个有钱的人,那么就直接执行 if 下面的语句,不需要再去判断帅不帅了,如果他没钱,就会再去判断他帅不帅,如果帅才执行 if 下面的语句。

虽然我没钱也不帅,但是我骚,可不可以嫁给我?

Python中的循环语句

不知道你有没有听过这么个东西:除去睡眠,我们每个人只能活1万多天,有些人活了1万多次,而有些人呢,则只是活了1天,而重复了1万多次。

我希望我的读者不要成为后者,咱们每天提升自己一点点,活出个样子来。

好阔怕,我不要重复~~

在 Python 的世界里面,可以用 while 和 for 来表示重复,也就是循环。

while循环

1
2
3
while 活着:

每天做着一样的事情。

这样写的意思就是,只要你活着,就一直不断的执行while下面的语句。

我们可以来写一个抛硬币的 python 程序,我们事先定义好硬币的正反面,然后让用户猜,如果用户猜对了就奖励一个吻,猜错了就继续猜,直到让他猜中为止。

打开我们的 IDLE,代码撸起来:

首先定义一个变量,我们的值定义为正面:

coin = "正面"

接着定义一个 flag :

flag = True

然后我们写一个循环:

1
2
3
4
5
6
7
8
9
while flag :

guess = input("请猜一下是正面还是反面:")

if(guess == "反面") :
print("你猜错了,继续猜")
elif(guess == "正面") :
print("恭喜你猜对了,奖励你一个吻")
flag = False

执行:

解释一下:当 while 发现 flag 为 true 的时候,就会一次又一次的执行执行 while 下面的一句,直到我们猜中之后,我们就将flag 这个变量改为 false ,while 发现为 false 的时候就不往下循环了。

for循环

while 可以做到在条件为真的时候反复的执行,不过有时候我们需要在特定范围循环,比如说我们要在第一天到第五天每天啪啪啪一次,那么这时候用 for 就再适合不过了:

1
2
3
4
days = [1,2,3,4,5]

for day in days :
print("第" + str(day) + "天啪啪啪")

我们来运行下:

可以看到第一次执行,day就是1,第二次执行day就是2,它就这样一直循环下去,没有一点念想。

终止循环break

有一天你突然发现,我不能再这么下去了,不能再重复的过这样的日子了,得有点改变,跳出这个重复的怪圈,那么对于 Python 来说,用break:

1
2
3
4
while 活着:
重复的过日子。
if(醒悟):
break

通过 break 呢,就可以跳出这个循环了。

continue

有时候我们在循环里面,在某个地方不希望它循环下去,先跳过本次接下来的东西,直接执行下一次,这时候我们就可以用 continue了,来试试:

Python中的函数

你可以把函数当做是一个「特定的小程序」,可以用它们来执行特定的事情。

Python中有内置了许多「特定的小程序」,我们可以非常方便的直接调用它们来执行我们想要操作的东西,这叫内置函数。

另外我们也可以根据我们自己的需要来创造「特定的小程序」,这叫自定义函数。

定义函数

假设我们要自己定义一个函数,这个函数用来叫:亚麻跌,哈哈,想想我们一调用这个函数,它就叫「亚麻跌」。是不是很好玩。

像这样定义一个函数:

1
2
def jiao():
print("亚麻跌~~~")

那么当我们要调用它的时候只要这样「jiao()」就可以了。

用 IDLE 来试一试吧:


来解释一下:

1
2
def jiao():
print("亚麻跌~~~")

这里的 def 就是一个关键字来的,代表我们要去定义一个函数,而 jiao 就是函数名称,当我们要使用这个函数的时候直接调用它就可以了。而 print(”亚麻跌~~~”) 就是函数体,也就是它所具备的功能实现。

函数的形参和实参

我们既然定义了一个会叫床的函数了,那么每调用一下它就叫一下是不是不太爽?如果我们能调用这个函数,然后传个数字给它,这个数字是多少,它就叫多少次,岂不是更好?

可以这样:

1
2
3
def jiao(times) :
for time in range(times) :
print("亚麻跌~~~")

在这里我们定义了一个 times 的参数,接下来我们通过这个range用内置函数生成一个序列,接着用 for 循环,这样子当我们调用函数并传一个数字进去,它就能根据这个数字,去叫相应的次数了。

比如我们调用 jiao(5),那么它就会叫 5 次。


那么如果我们想要用户输入多少次,就让它叫多少次,怎么玩呢?想必你看过之前的文章也知道怎么玩了:


可以看到我们这里的 jiao(int(time)) 传入的是一个变量,那么这样传递的参数叫做形参。而我们刚刚 jiao(5)传递的是一个实实在在的数字,我们叫实参

局部变量和全局变量

我们在函数里面定义的变量,只有函数里面才可以用,在函数外面是使用不到这个变量的,所以这个变量存在函数这个局部里,我们叫这个变量为局部变量。

比如说:

1
2
3
4
5
def jiao(times):
x = 1

for time in range(times+x):
print("亚麻跌~~~")

这里的x就是局部变量啦。

知道了什么是局部变量之后我们在来了解一下什么是全局变量,其实顾名思义,全局嘛~ 那么就是哪里都可以使用这个变量咯。比如说我们在函数内想要更改外边的变量,怎么办呢?这时候我们可以使用 global:

1
2
3
4
5
6
7
8
9
10
def jiao(times):

global x
x = 5

for time in range(times+x):
print("亚麻跌~~~")

x = 2
jiao(5)

那么这里 x 就是全局变量。

return返回值

有时候我们需要调用一个函数返回给我们结果,比如我们定义了一个加法计算的函数,我们希望扔两个数给它,它直接计算好然后返回给我们,那么这时候我们就可以用到 return:

定义一个加法的函数,并返回结果:

1
2
def addition(x,y):
return x+y

那么我们调用的时候:

print(addition(5,6))

直接返回 11 。

docString

很多程序员其实不太喜欢写文档的,因为觉得文档这事儿好像不关自己的事情,代码才是。老子写个代码而已,凭什么还要我写文档?

Python 有个叫做 docString 的东西完美解决了这问题,让你直接在代码中写文档,其实说白了就是给代码写点注释,什么语言都会有给代码写注释的,不过 Python 的 docString 可以直接把你的注释变成文档,是不是很厉害?

我们可以通过 help(requests) 或者 requests.doc 就可以访问到它的文档了。

接下来我们自己写一个docString吧。

我们定义一个叫 myDoc 的函数,传入两个参数,再写一下docString,告诉别人我们的函数是干嘛的,传入的参数是什么,返回什么。

1
2
3
4
5
6
7
8
9
def myDoc(param1 ,param2):
"""
this is myDoc function
:param param1: this is a first param
:param param2: this is a second param
:return: param1 + param2
"""
print(param1 + param2)
return param1 + param2

是不是一目了然。

而且我们还可以使用 sphinx 的 autodoc 自动从docString生产api文档。是不是很方便呢?

模块

你可以把模块理解为一个 .py文件,这个文件里面包含了所需要的函数和变量,那么下次我们任何一个程序要使用这里面的东西,我们只需要把这个模块导入到我们的程序里面来,就可以直接用了,简直不要太爽。造轮子多麻烦啊,拿来就用是了。

其实 Python 有内置了一些模块,我们可以直接引用,还有一些第三方模块,也就是我们可以自己创建模块,安装好模块就可以直接使用了。

使用模块

如果我们要使用一个模块,可以将这个模块导入,使用 import ,比如我们要导入 Python 的内置的 sys 模块(sys模块包含了与Python解释器和它的环境有关的函数),那么我们就可以使用 import sys:


创建自己的模块

创建自己的模块其实就是自己写了个程序,然后给别人import,我们来写一个模块:

记住,这模块要保存到和你即将要用的 Python 程序的同一目录下,然后这文件必须是 .py 结尾不用我说了吧。

接着我们就来使用我们自己的模块吧:

运行一下:

可以看到我们不仅会使用模块,而且会自己创建模块了,真是越来越牛逼了。

安装第三方模块

世界那么大,牛人那么多,牛人写的模块,我们直接拿来用,不是很爽吗?

那么我们要使用他们写的模块之前要先将他们的模块安装到我们的 Python 环境来,然后才可以使用。

首先你要确保你的电脑已经安装好了 pip,如果你在命令行工具中输入 pip 可以像我这样那就说明你已经安装好了 pip:

推荐一个网站给你们:https://pypi.org/ 这个网站聚集了一堆牛逼的模块,你可以通过搜索任何你想要的模块:

比如说我要安装一个叫做 BTrees 的模块,那么我只需要使用「pip install BTrees」 这个命令就可以安装了。

安装完之后呢,你就可以通过 import 直接使用模块了。

面向对象

python创建一个类

为了让你更好的理解类和对象,我来举一个例子,哆啦A梦大家都很熟悉吧,那个矮胖矮胖的家伙,口袋里面有着许多我们梦寐以求的东西。

我们可以把哆啦A梦理解为它是一个对象。如果我们创建一个叫做哆啦A梦的类,那么这个类的实例,我们就叫做哆啦A梦对象。

在 python 中,可以用 class 来定义一个类,比如:

1
class DuoLaAMeng:

那么当我们要去使用这个类的对象的时候我们可以这样:

1
duola = DuoLaAMeng()

在这里呢,我们定义了一个叫做 duola 的变量,指向的是哆啦A梦这个实例。

类中的方法使用

我们的对象肯定是有一些属性给我们用的,比如说哆啦A梦这个对象可以给我们提供竹蜻蜓,所以我们可以在类中定义一些方法给别人去使用。

我们创建一个类,并且给它定义一个获取竹蜻蜓的方法:

1
2
3
class DuoLaAMeng:
def getZhuQingTing(self):
print("给一个竹蜻蜓")

那么当我们要调用的时候就可以这样子:

1
2
duola = DuoLaAMeng()
duola.getZhuQingTing()

我们可以看到在定义 getZhuQingTing 这个方法的时候,定义了一个 self 这个参数,其实这个参数指的是DuoLaAMeng对象本身,这就和我们普通定义的函数有些许区别。

init函数

我们在调用对象的时候,有些东西是可以初始化的,这个时候 Python 就给我们提供了一个初始化函数,也就是当我们去调用这个对象的时候,它会先去执行 init 这个函数。举个例子你就明白了:

1
2
3
4
5
6
7
8
9
class DuoLaAMeng:
def __init__(self, name):
self.name = name

def getZhuQingTing(self):
print("给"+self.name+"一个竹蜻蜓")

duola = DuoLaAMeng("大雄")
duola.getZhuQingTing()

我们定义了一个 DuoLaAMeng 类, 并且给了一个初始化函数,当别人调用这个类的时候呢,传一个 name 进来,我们就可以对这个名字进行初始化了。

继承

如果我们想要再定义一个类似哆啦A梦的对象,比如说哆啦A梦的儿子对象,那么这时候我们用继承来实现,继承就是实现代码重用的方式。

如果说哆啦A梦的儿子叫做哆啦B梦,那么当我们的哆啦B梦继承了它的爸爸哆啦A梦的时候,哆啦B梦拥有哆啦A梦的所有功能。

在 Python 中继承的表现形式只这样的:

1
class 哆啦B梦(哆啦A梦):

这样就说明了哆啦B梦是哆啦A梦的儿子。

举个例子:


我们在这里定义了一个叫做 DuoLaAMeng 的类,然后定义了两个方法,一个是初始化,一个是获取竹蜻蜓。

接着我们创建了 DuoLaBMeng 这个类来继承 DuoLaAMeng ,可以看到 DuoLaBMeng 其实啥也没做,但是它就是拥有了DuoLaBMeng 的所有功能。

这种继承的方式很好,比如我们以后要创建 DuoLaCMeng ,直接继承 DuoLaAMeng 就可以用所属的方法,以后我们要增加什么共同的功能的时候,只需要在父类 DuoLaAMeng 添加就好了,它的子类们都可以使用。

多态

DuoLaBMeng 和 DuoLaCMeng 是 DuoLaAMeng 的儿子,我们也可以把它的儿子当做 DuoLaAMeng 对象来使用,比如说有一天 DuoLaAMeng在忙,这时候大雄完全可以把它的儿子们当做是 DuoLaAMeng 来使用,完全木有问题,这就是面向对象中多态的意思。

但是有些子类是独具特色的,比如 DuoLaBMeng 可以从口袋中拿出充气娃娃,而它的父亲 DuoLaAMeng 没有这个功能。

这时候父类 DuoLaAMeng 是不可以把它当做子类DuoLaBMeng 来用的,也就是子类可以用父类的方法,但是父类不能用子类的方法。


异常

知道代码有错还狂往下写?是的没错,就是明明知道可能代码会有错误,但是我们还是往下写。就是这么任性!

异常捕获

有时候我们对我们的代码的报错是可预知的,比如我们想让 Python 帮我们打开一个小黄文的文件,比如 yellow.txt,可是我们的电脑不一定有,如果这个时候没有的话我们的代码会报错的对吧?

1
2
document = open('yellow.txt')
print('filename:' + document.name)

运行之后可以看到这里报错:

1
FileNotFoundError: [Errno 2] No such file or directory: 'yellow.txt'

告诉我们没有这个文件。

但是如果这时候我们还想往下运行怎么办呢?

那就可以把这异常给捕获掉,使用 try...except...finally...

try:用来包裹我们可能存在错误的代码;
except:当发现错了就会执行这里
finally:无论怎么样最后都会执行到的。

举个例子你就明白了:

1
2
3
4
5
6
7
try:
document = open('yellow.txt')
print('filename:' + document.name)
except FileNotFoundError as e:
print("error:" , e)
finally:
print("最后执行的语句")

我们这里打开 yellow.txt ,Python发现不存在,那么就执行except下的语句,finally最后也会被执行:

1
2
error: [Errno 2] No such file or directory: 'yellow.txt'
最后执行的语句

那么这样子的话,以后我们就可以将预料到的错误进行捕获,然后对其进行操作。

抛出异常

有时候我们没有去处理异常, Python 也会给我们报出错误,这是因为 Python 有个 BaseException 的异常基类,当Python发现我们的代码错误的时候,又没人去处理,它就会层层的往上抛出错误,直到最上级。

我们可以自己定义一个异常类:

1
2
3
4
5
6
7
8
class MyError(Exception):
pass

def foo(value):
if(value==0):
raise MyError('ERROR %s' % value)

foo(0)

可以看到我们自定义了一个叫做MyError的异常类,继承与Exception,当我们传入 0 的时候就会抛出异常。在这里我们使用到的关键字是raise,就是用来抛出异常的意思

放个异常让你心情疙瘩一下,哈哈哈:

1
2
3
4
5
6
Traceback (most recent call last):
File "G:/test.py", line 11, in <module>
foo(0)
File "G:/test.py", line 9, in foo
raise MyError('ERROR %s' % value)
__main__.MyError: ERROR 0

ok,有了这两招,妈妈再也不用担心,我错误的代码该如何安放了。

python 中的数据结构

什么是数据结构呢?就是存储一组相关数据的结构。

在 python 里面呢,有三种内置好了的数据结构,它们分别是「列表」、「元组」、「字典」。

列表

我们应该都很熟悉列表吧,一个列表里面,有多个列表项,每一项就是具体的内容:

看,这个列表是不是很熟悉?那么在 python 中要表示一个列表可以用到 list 这个对象。例如:

avlist = ['亞洲無碼原創區','亞洲有碼原創區','歐美原創區','動漫原創區']

可以看到,我们用中括号把每个列表项的内容用逗号隔开,就成了一个 list 对象,然后我们将这个对象赋值给 avlist 这个变量。

在 python 中想要知道怎么运用 list 这个对象,我们可以在python 解释器中输入 help(list) 得到帮助:

来看看这里例子怎么使用 list 的吧:

运行一下:

讲讲过程:

首先我们定义了一个叫做 avlist 的列表对象,这个列表中有一些内容 [‘亞洲無碼原創區’ ,’亞洲有碼原創區’ ,’歐美原創區’ ,’動漫原創區’ ]

我们通过 len 这个列表对象的方法可以得到列表中的条目数。

可以通过 for 循环来获取列表中每一个项的内容。

我们可以通过 append 方法在列表中添加条目。

使用了 sort 对列表中的内容进行排序。

列表中的内容可以通过下标索引获取,从0开始,例如avlist[0] 就是获取avlist这个列表的第一个条目。

通过上面我们可以看到, list 这个列表对象是可变的数据类型,什么意思呢?就是我们可以对列表里面的内容进行修改,删除,添加等操作。

元组

其实元组和列表是差不多的,不过它们有一点区别就是:元组是不可变的数据类型,也就是说元组里面的内容是不能进行修改,删除,添加等操作的。

元组使用圆括号来表示,例如:avlist = (’亞洲無碼原創區’ ,’亞洲有碼原創區’ ,’歐美原創區’ ,’動漫原創區’ )

元组通常被用来打印语句:


字典

如果你想描述 苍井空 的特点是怎么样怎么样,波多野结衣的特点是怎么样怎么样,那么你就可以用到字典啦。

字典是以键和值组成的,键呢,是不可变的,而值可变。

字典的表示如下:

nvyou = {‘苍井空’:’美丽大方’,’波多野结衣’:’身材特好’}

接下来看看怎么使用字典吧:


可以看到,我们可以通过字典对象用[键]来获取对应的值,也可以往字典里面添加数据,我们可以用字典的items()方法获取字典中的具体内容。

序列

我们之前所说的 列表,元组都是序列,序列还有一个叫做 字符串,为什么它们会被叫做序列呢?

那是因为它们有一些特别的地方,比如:索引,切片,相加相乘,成员资格。

索引

对于序列来说,序列里面的每个元素都有一个编号,而这个编号是从 0 开始的,例如下面的这个序列,第 0 号就是:亞洲無碼原創區,第 1 号就是亞洲有碼原創區,以此类推。

这里我们所说的编号就是索引,我们可以通过索引去获取列表的具体想要的内容,如果我们的索引是负数的时候,那么 Python 就会从序列的最后一个元素开始数起,比如说上面这个序列,如果我们用索引 -1 ,那么就可以获取得到「在线成人电影」这个元素。

切片

可能你这时候想说了,我用索引只能获取到一个元素,那如果我想在一个序列里面获取部分元素怎么玩?那么这时候就可以用切片来获取。

比如 [1:3],就代表我要获取序列中第一个元素(包含)到第三个元素(不包含)的所有内容:

这里定义一个列表:

avlist = ['亞洲無碼原創區','亞洲有碼原創區','歐美原創區','動漫原創區']

然后我们通过 avlist[1:3] 就可以获取到:

['亞洲有碼原創區', '歐美原創區']

切片最常用的还是在使用字符串这个序列中,比如:

1
2
url = input("请输入你的网站:")
print("主机名是:"+ url[11:-4])

在这里我们就可以通过切片的方式,来获取字符串这个序列的部分内容,比如这里我们输入:http://www.google.com,那么这个时候我们就可以获取到[11:-4]之间的内容,也就是 google。

切片还有个叫做步长的东西,还是拿刚刚那个序列为例:

avlist = ['亞洲無碼原創區','亞洲有碼原創區','歐美原創區','動漫原創區','國產原創區','在綫成人影院 ']

在这个序列中我们如果通过 avlist[1,-1],那么python会从第一个元素逐一的去获取范围内的内容,也就是一步一步一个脚印的获取,那如果我们想要让它的步伐跨的大一点呢?每一步跨两个元素,那就可以这样:

相加相乘

序列是可以相加相乘的,比如我们之前在说Python : Hello World !中就知道了字符串的拼接,其实就是序列的相加。



成员资格

如果我们想要判断一个元素是不是在这个列表中,那么我们就可以用到 in 这个关键字,如果存在的话, python 就会给我们返回 True ,如果不存在的话,那么 Python 就会给我们返回 Fasle:

Python中的IO

我们到时候肯定是需要用到对文件进行读写操作的,也就是IO,但是我们不能直接去操作文件,我们需要去告诉操作系统,我们想操作什么文件,然后操作系统帮我们操作。

读取文件

我们先创建个叫做 xiaohuangwen.txt 的文件吧:

python有个内置的函数叫做 open() , 我们可以通过它直接打开文件,打开完文件就可以读取了,但是有可能会报错,就是文件不存在,这个时候我们可以用到上次说的 try…finally 来处理异常:

1
2
3
4
5
6
try:
f = open("G:/xiaohuangwen.txt","r",encoding="UTF-8")
print(f.read())
finally:
if f:
f.close()

我们通过 open 打开了 xiaohuangwen.txt 这个文件。 r 就是读的意思, encoding就是定义好文件编码。

接着我们就打印出我们 read 出来的文件啦:

最后一定要记得将文件 close 掉,这样才不会造成系统浪费资源。

有时候你在读取文件的时候,是不是觉得每次都要 try…finally 很麻烦? 贴心的 Python 帮我们简化了流程,我们只要直接这样写就可以了:

1
2
with open("G:/spider/xiaohuangwen.txt","r",encoding="UTF-8") as f:
print(f.read())

是不是简化了很多??

写入文件

写入文件内容也是一个道理,我们首先要打开文件,然后往里写内容,如果我们传入的参数是 ‘w’ 的话,它会覆盖原来的文件,而我们传入 ‘a’ 则可以在文件末尾追加内容:

1
2
with open("G:/spider/xiaohuangwen.txt","a",encoding="UTF-8") as f:
print(f.write("\n我想看苍老师啊!"))

ok,运行之后你会发现,你已经把内容写进去了,是不是很简单?

文件存储器

Python 有一个叫做 pickle 的模块,有了它,我们就可以在一个文件中持久的存储我们的女朋友,哦,不是,可以持久的存储我们的对象。

还有一个叫做 cPickle 的模块,它是用 C 写的,所以它更加牛逼一点,比 pickle 速度快,要快上 1000 倍,所以我么用 cPickle 这个模块会好点。

不过在 Python3 已经将 cPickle 改名为 pickle 了,所以我们就可以直接 import pickle 就可以啦。

写个文件存储器的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import pickle as p


# 我们要存储内容的文件名
girlfriendlistfile = 'girlfriend.data'

girlfriends = ['波多野结衣', '苍井空', '小泽玛利亚']

# 把我们的女朋友写到文件里,然后存储器存储
with open(girlfriendlistfile,'wb+') as f:
p.dump(girlfriends, f)
f.close()

del girlfriends # 删掉我们的女朋友

# 把我们的女朋友读回来!!
with open(girlfriendlistfile,'rb+') as f:
list = p.load(f)
print (list)

这就是存储器的使用,是不是so easy?

用python给自己写一个操作界面

Python 有一个自带的库叫做 tkinter ,用它我们可以写出系统的操作界面,不管你是 Mac OS 系统,还是 Windows 系统,它都可以生成相对应的操作界面。这就是所谓的跨平台。

原理就是我们使用 Python 的代码去调用 Tkinter, Tkinter 已经封装了访问TK的接口,这个接口是一个图形库,支持多个操作系统,通过它我们就可以调用我们系统本身的GUI接口了。

接下来我们用代码玩一下吧:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from tkinter import *
import tkinter.messagebox as messagebox

class MyApp(Frame):

def __init__(self,master=None):
Frame.__init__(self,master)
self.pack()
self.createWidgets()

def createWidgets(self):
self.helloLabel = Label(self,text="世界上最帅的人是谁?")
self.helloLabel.pack()
self.quitButton = Button(self,text="谁呢?",command=self.who)
self.quitButton.pack()

def who(self):
messagebox.showinfo("答案","当然是小帅b啦")


myapp = MyApp()
myapp.master.title('hello')
myapp.mainloop()

在这里:

  1. 我们导入了 tkinter 的相关模块
  1. 定义了初始化函数,通过 pack() 方法将我们的组件传给父容器
  1. 自定义一个创建组件的方法,我们创建了一个标签和一个按钮,这个按钮被点击后就会触发 who 这个方法
  1. 我们通过 messagebox 来显示一个提示框
  1. 实例化我们的 APP,然后通过主线程来监听我们的界面操作

运行后如下:

Python的互联网编程

你怎么还在用Python写的单机版程序?
因为我现在才刚学不久
现在开发的基本上都是互联网程序了,你要不要跟我一起学一下用Python网络编程?
哇!真的吗?大佬求带!
低调低调,说到网络编程,那么我们先要了解互联网。
我了解,互联网就是把许多网络连接起来。
恩,不错,那你知道什么是TCP,UDP吗?
em,以前听过,现在有点忘了,你可以给我说道说道吗?
可以,我们以前的计算机网络,为了能够互相通信,很多厂商都有自己的一套协议,这就弄得很乱,因为互不兼容,所以通信起来很费劲。后来呢,为了让成千上万的计算机连接起来,定义了两个标准的协议,一个是TCP,一个是 IP,也就是我们现在简称的 TCP/IP 协议。
也就是说我们遵循 TCP/IP 协议就可以互联了是吧!
恩,通信的时候,双方要知道对方的标识,才能通信。
那。。大佬能告诉我下 TCP 和 IP 的区别吗?
当然可以,那我先告诉你 IP 协议吧,假如我要发信息给你,我们都在互联网上,都有自己的 IP 地址和路由,那么当我发信息给你的时候呢,IP 协议就负责将数据进行传输,这些数据被分割成一小块一小块的,通过 IP 包给发送过去。因为们之间在互联网上是有很多链路的,所以路由就会将一小块一小块的数据包逐个进行转发,直到发送到你的IP地址。但是它不能够保证数据都能到达,也保证不了能够按顺序的到达。
啊~那如果丢失怎么办?有什么办法吗?
有!那就是 TCP 协议,TCP协议建立在IP协议之上的。TCP协议会建立可靠连接,保证数据包按顺序到达。TCP协议会通过握手建立连接,确保对方按顺序收到,如果包丢掉了,就自动的重新再发。
哦,明白了,那刚刚你说的 UDP 又是?
 我们已经知道了 TCP 是面向连接的,比较可靠,而UDP协议呢,它是面向无连接的,也就是我只要知道你的IP地址和端口就可以直接给你发送数据了,不需要先跟你握手,不过数据能不能到达就不知道了。
哦,明白,就是TCP可靠,UDP传输效率高。
对头,所以呢,如果不要求数据可靠到达的话就可以用UDP。那么接下来我们就用 Python 来进行 TCP 和 UDP 的编程吧。
太好了!!
不过在此之前跟你讲一下 Socket 的东西,因为等下我们要用到,Socket 在互联网编程中表示建立了一个互联网连接,Socket知道了对方的IP地址、端口号、协议,就可以建立连接了。
恩,感谢大佬,明白了。

Python 中的 TCP 编程

###TCP客户端的编写
我们现在访问一些网页什么的,这些网页是在服务器端的,而我们访问的设备属于客户端。

比如我们现在通过浏览器访问这个地址:

http://www.meizitu.com/

那么会得到好多小姐姐的图片哈哈:

那么我们怎么通过 Python 来建立可靠的 TCP 连接,获取到这些图片呢?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 导入socket这个库
import socket

# 创建一个socket对象
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# 开始建立TCP连接
s.connect(("www.meizitu.com",80))
# 连接后,发送请求
s.send(b'GET / HTTP/1.1\r\nHost: www.meizitu.com\r\nConnection: close\r\n\r\n')
# 接收数据
buffer = []
while True:
d = s.recv(1024)
if d:
buffer.append(d)
else:
break
# 把字节连接起来
data = b''.join(buffer)

# 关闭连接
s.close()

# 把数据读取出来

with open('meizi.html','wb') as f:
f.write(data)

运行之后,我么就有了咱们的妹纸文件:

打开有惊喜。

TCP 服务端的编写

服务端一般都是一直在运行着的,等待着客户端来连接,然后给出请求响应,服务端需要提供 ip 地址和端口给客户端去连接。

首先我们来写一个简单服务端的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import socket

# 创建socket对象
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

# 绑定监听端口
s.bind(('127.0.0.1',8888))

# 监听
s.listen(1)

while True:
# 接收连接
sock,addr = s.accept()
print("有人连进来了")
sock.send(b'hei man, are you ok?')
sock.close

当有人连接进来我们就给他发一句:hei man,are you ok ?

接着我们再来写个客户端的连接过去:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 导入socket这个库
import socket

# 创建一个socket对象
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# 开始建立TCP连接
s.connect(("127.0.0.1",8888))
# 接收数据
buffer = []
d = s.recv(1024)
buffer.append(d)

# 把字节连接起来
data = b''.join(buffer)
print(data)

# 关闭连接
s.close()

然后先运行我们的服务端,再运行客户端:


Python中的 UDP 编程

我们来先写服务端:

1
2
3
4
5
6
7
8
9
10
11
12
13
import socket

# 创建socket对象,这里传入的是SOCK_DGRAM,代表UDP
s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

# 绑定监听端口
s.bind(('127.0.0.1',8090))

while True:
# 接收连接
data,addr = s.recvfrom(1024)
print(addr)
s.sendto(b'hei man, are you ok?',addr)

可以看到,在这里我们不需要跟对方连接,只要知道地址就直接发送过去就可以了。

客户端:

1
2
3
4
5
6
7
8
9
10
11
import socket

# 创建一个socket对象
s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

s.sendto(b'ha',("127.0.0.1",8090))
# 接收数据
print(s.recv(1024).decode('utf-8'))

# 关闭连接
s.close()

运行如下:

把你的Python程序打包成exe可执行文件

在这篇文章我们就说到了怎么使用Python爬取性感美女并保存到本地。还没了解的童鞋可以先看一下。

在这里呢,我们要使用 PyInstaller 来将我们的爬虫小程序打包成一个 exe 执行文件,然后在没有安装python环境的情况下也可以双击直接运行。

首先我们要通过 pip 来安装 PyInstaller。

1
pip install pyinstaller

可以先去喝杯茶,等它一顿安装:

喝完茶,差不多也安装完成了。

我们可以使用 Pyinstaller 的 F 选项来打包:

-F, –onefile Create a one-file bundled executable.

以我们的爬虫小程序为例,我们要将其打包成一个 exe ,那么我们就可以这样:

pyinstaller -F .\meizi.py

这里的 meizi.py 就是我们的项目名称。在执行的时候,Pyinstall帮我们在当前目录创建了 meizi.spec、build文件夹、dist文件夹、pycache文件夹。

双击dist文件夹进去一看,你会发现有一个exe执行文件。它就是一个应用程序啦。

接着我们双击一下,就开始运行啦~

可以看到它按我们的程序执行,创建了一个 meizi 的文件夹,并且去妹子网站爬取美女图片然后下载到我们这个文件夹里面。

爽!!!

打开我们的meizi文件夹,看看图片爬的怎么样了:

(完)

写在最后

你能看到这里也是厉害的了,我特别为了Python开了一个公众号,名字叫做「学习python的正确姿势」,里面放了一堆福利,在里面发送python有惊喜。快关注一波。

我的相关文章

参考文章

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×