zhigu34
Get up early,Stay up late
古迹年华
Python | 路人甲的Python总结

前言

知乎:路人甲
微博:玩数据的路人甲
微信公众号:一个程序员的日常

在知乎分享已经有一年多了,之前一直有朋友说我的回答能整理成书籍了,一直偷懒没做,最近有空仔细整理了知乎上的回答和文章另外也添加了一些新的内容,完成了几本小小的电子书,这一本是有关Python方面的。

还有另外几本包括我的一些数据分析方面的读书笔记、增长黑客的读书笔记、机器学习十大算法等等内容。将会在我的微信公众号:一个程序员的日常进行更新,同事也可以关注我的知乎账号:路人甲 及时关注我的最新分享用数据讲故事。

一、如何学习Python

学习Python大致可以分为以下几个阶段:

  1. 刚上手的时候肯定是先过一遍Python最基本的知识,比如说:变量、数据结构、语法等,基础过的很快,基本上1~2周时间就能过完了,我当时是在这儿看的基础:Python 简介 | 菜鸟教程
  2. 看完基础后,就是做一些小项目巩固基础,比方说:做一个终端计算器,如果实在找不到什么练手项目,可以在Codecademy上面进行练习。
  3. 如果时间充裕的话可以买一本讲Python基础的数据比如《Python编程》,阅读这些书籍,在巩固一遍基础的同时你会发现自己诸多没有学习到的边边角角,这一步是对自己基础知识的补充。
  4. Python库是Python的精华所在,可以说Python库组成并且早就Python,Python库是Python开发者的利器,所以学习Python库显得尤为重要:The Python Standard Library,Python库很多,如果你没时间全部看完,不妨学习一遍常用的Python库:Python常用库整理 – 知乎专栏
  5. Python库是开发者利器,用这些库你可以做很多很多东西,最常见的网络爬虫、自然语言处理、图像识别等等,这些领域都有很强大的Python库做支持,所以当你学了Python库之后,一定要第一时间进行练习。如何寻找自己需要的Python库呢?推荐我之前的一个回答:如何找到适合需求的Python库?
  6. 学习使用这些Python库,此时的你应该是对Python十分满意,也十分激动能遇到这样的语言,这就是这个时候不妨开始学习Python数据结构与算法,Python涉及模式,这是你进一步学习的一个重要步骤:faif/python-patterns
  7. 当度过艰难的第六步,此时选择你要研究的方向,如果你想做后端开发,不妨研究Django,再往后,就是你自己自由发挥了。

二、一些免费课程推荐

以下课程都为免费课程

1.Python零基础相关

适用人群:Python零基础的初学者、Web开发程序员、运维人员、有志于从事互联行业以及各领域应用Python的人群

2.Python Web方向

3.Python 爬虫

4.Python数据分析方向

三、爬虫需要哪些知识

要学会使用Python爬取网页信息无外乎以下几点内容:

  1. 要会Python
  2. 知道网页信息如何呈现
  3. 了解网页信息如何产生
  4. 学会如何提取网页信息

第一步:Python是工具,所以你必须熟练掌握它,要掌握到什么程度呢?如果你只想写一写简单的爬虫,不要炫技不考虑爬虫效率,你只需要掌握:

你甚至不需要掌握函数、异步、多线程,当然如果想要提高自己小爬虫的爬虫效率,提高数据准确性,那么记住最好的方式是去系统的学习一遍Python,去哪儿学? Python 教程

第二步:知道网页信息如何呈现?
你首先要知道所需要抓取的数据是怎样呈现的,就像是你要学做一幅画,在开始之前你要知道这幅画是用什么画出来的,铅笔还是水彩笔…可能种类多样的,但是放到网页信息来说这儿只有两种呈现方式:

  1. HTML
  2. JSON

HTML是用来描述网页的一种语言
JSON是一种轻量级的数据交换格式

第三步:数据怎么来?数据当然是从服务器反馈给你的,为什么反馈给你?因为你发出了请求。
“Hi~,服务器我要这个资源”
“正在传输中…”
“已经收到HTML或者JSON格式的数据”

这个请求是什么请求?要搞清楚这一点你需要了解一下http的基础知识,更加精确来说你需要去了解GET和POST是什么,区别是什么。也许你可以看看这个:浅谈HTTP中 GET 和 POST 的区别 – hyddd – 博客园

很高兴你使用的是Python,那么你只需要去掌握好快速上手 – Requests 2.10.0 文档requests可以帮你模拟发出GET 和 POST 请求,这真是太棒了。

第四步:现在我们已经拿到了数据,我们需要在这些错乱的数据中提取我们需要的数据,这时候我们有两个选择。

第一招:万能钥匙
Python 正则表达式指南,再大再乱的内容,哪怕是大海捞针,只要告诉我们这个针的样子我都能从茫茫大海中捞出来,强大的正则表达式是你提取数据的不二之选。

第二招:笑里藏刀
Beautiful Soup 4.2.0 文档,或许我们有更好的选择,我们把原始数据和我们想要的数据的样子扔个这个Beautifulsoup,然后让它帮我们去寻找,这也是一个不错的方案,但是论灵活性,第二招还是略逊于第一招。

第三招:双剑合璧
最厉害的招式莫过于结合第一招和第二招了,打破天下无敌手。

基础知识我都会了,可我还是写不了一个爬虫啊!

客官别急,这还没完。

以下这些项目,你拿来学习练练手。

一些教学项目你值得拥有:

还不够?这儿很多:

四、爬虫进阶

爬虫无非分这几块:分析目标、下载页面、解析页面、存储内容,其中下载页面不提。

  1. 分析目标
    所谓分析就是首先你要知道你需要抓取的数据来自哪里?怎么来?普通的网站一个简单的POST或者GET请求,不加密不反爬,几行代码就能模拟出来,这就是最基本的,进阶就是学会分析一些复杂的目标,比如说:淘宝、新浪微博登陆以及网易云的评论信息等等。
  2. 解析页面
    解析页面主要是选择什么库或者哪些库结合能使解析速度更快,可能你一开始通过种种地方了解到了bs库,于是你对这个库很痴迷,以后只要爬虫,总是先写上:
import requests
from bs4 import BeautifulSoup

当然bs已经很优秀了,但是并不代表可以用正则表达式解析的页面还需要使用bs,也不代表使用lxml能解决的还要动用bs,所以这些解析库的速度是你在进阶时要考虑的问题。

  1. 存储内容
    刚开始学爬虫,一般爬取的结果只是打印出来,最后把在终端输出的结果复制粘贴保存就好了;后来发现麻烦会用上 xlwt/openpyxl/csv 的把存储内容写入表格,再后来使用数据库 sqlite/mysql/neo4j 只要调用了库都很简单,当然这是入门。

进阶要学习如何选择合适的数据库,或存储方式。当爬取的内容过千万的时候,如何设计使存储速度更快,比如说当既有人物关系又有人物关系的时候,一定会用neo4j来存储关系,mysql用来存储用户信息,这样分开是因为如果信息全部存入neo4j,后期的存储速度十分的慢。

当你每个步骤都能做到很优秀的时候,你应该考虑如何组合这四个步骤,使你的爬虫达到侠侣最高,也就是所谓的爬虫策略问题,爬虫策略学习不是一朝一夕的事情,建议多看看一些比较优秀的爬虫设计方案,比如说Scrapy。

除了爬取策略以外,还有几点也是必备的:

  1. 代理策略以及多用户策略

    代理是爬虫进阶阶段必备的技能,与入门阶段直接套用代理不同,在进阶阶段你需要考虑如何设计使用代理策略,什么时候换代理,代理的作用范围等等,多用户的爬取策略考虑的问题基本上与代理策略相同。
    
  2. 增量式抓取以及数据刷新

    比如说你抓取的是一个酒店网站关于酒店价格数据信息的,那么会有这些问题:酒店的房型的价格是每天变动,酒店网站每天会新增一批酒店,那么如何进行存储、如何进行数据刷新都是应该考虑的问题。
    
  3. 验证码相关的一些问题

    很多人提到验证码,我个人认为验证码不是爬虫主要去解决的问题,验证码不多的情况下载到本地自己输入验证码,在多的情况下考虑接入打码平台。
    

五、爬虫面试指南

前段时间快毕业,而我又不想找自己的老本行Java开发了,所以面了很多Python爬虫岗位。因为我在南京上学,所以我一开始只在南京投了简历,我一共面试了十几家企业,其中只有一家没有给我发offer,其他企业都愿意给到10K的薪资,不要拿南京的薪资水平和北上深的薪资水平比较,结合面试常问的问题类型说一说我的心得体会。

第一点:Python
因为面试的时Python爬虫岗位,面试官大多数会考察面试者的基础的Python知识,包括但不限于:

  • Python2.x 与 Python3.x 的区别
  • Python的装饰器
  • Python的异步
  • Python的一些常用内置库,比如多线程之类的

第二点:数据结构与算法
数据结构与算法是对面试者尤其是校招生面试的一个很重要的点,当然小公司不会太在意这些,从目前的招聘情况来看对面试者的数据结构与算法的重视程度与企业的好坏成正比,那些从不问你数据结构的你就要当心他们把你当码农用的,当然以上情况不绝对,最终解释权归面试官所有。

第三点:Python 爬虫
最重要也是最关键的一点当然是你的Python爬虫相关的知识与经验储备,这通常也是面试官考擦的重点,包括但不限于:

  • 你遇到过的反爬虫的策略有哪些?
  • 你常用的反爬虫的方案有哪些?
  • 你用过多线程和异步吗?除此之外你还用过什么方法提高爬虫效率?
  • 有没有做过增量式抓取?
  • 对Python爬虫框架是否有了解?

第四点:爬虫相关的项目经验
爬虫重在实践,除了理论知识之外,面试官也会十分注重爬虫相关的项目:

  • 你做过哪些爬虫项目?如果Github最好
  • 你认为你做过的最好的爬虫项目是哪个?其中解决了什么难题?有什么特别之处?

以上是我在面过程中,会碰到的一些技术相关的问题的总结,当然面试中不光是技术这一点,但是对于做技术的,过了技术面基本上就是薪资问题了。

六、推荐的Python博客

如果是Python基础的话,廖雪峰的官方网站教程会是一个不错的选择:

当然很多刚接触Python的同学反映廖大大的教程中部分跳跃性太大,如果觉得跳跃性太大可以结合菜鸟教程一起看:

如果你英文稍好的话推荐还是看官方文档:Python 3.7.3 Documentation
中文版:Python 3.7.3 文档

如果不是为了学习Python基础的话,推荐几个其他博客:

七、Python如何进阶

很多人在学习编程之初都会碰到这种问题:学会了基础的语法了,但还是做不了项目,不知道如何下手

当初,我学习C的时候是这样、Java的时候是这样、Python的时候也是这样,其实不管什么语言、什么知识都是这样:理论基础知识 – 能动手做箱是有一道鸿沟的

那么如何突破这条鸿沟?中间的桥梁是什么?
其实题主自己已经回到出来了:照抄

所谓照抄前提是有样本。

首先找到一些简单易上手的项目,这些项目大多散落在Python实践相关的书籍中、Github上,这些实战项目知乎上都有很多推荐。

  1. 一些比较好的适合初学者动手的项目:

    另外知乎上这个问题下的一些推荐的项目还是非常适合新手练习的,可以作为参考:
    Python 的练手项目有哪些值得推荐?

  2. 大多数的Python书里面(除了纯理论书)都是有小项目的,而且书的一个优点是它会一步一步解释这样做的原因

    先照抄这些项目,实现这些小功能在电脑上能运行确认无误之后,回过头来看代码:

    • 有没有你不理解的地方,不理解的地方标记去搜索引擎或者书中找解释。
    • 学习作者设计这个项目的思路方法,并运用到接下来的项目,如果时间充裕,建议隔天再重新不看书的情况下自己实现一遍这些小项目。

如果你是跟着实战的书敲代码,很多时候项目都不会一遍运行成功,那么你就要根据各种报错去寻找原因,这也是一个学习的过程。

总结起来从Python入门跳出来的过程分三步:照抄、抄完理解、重现自己实现。

八、爬虫入门

想写这么一篇文章,但是知乎社区爬虫大神很多,光是整理他们的答案就够我这篇文章的内容了。对于我个人来说更喜欢那种非常实在的教程,这种教程对于想直接上手爬虫做一些小东西的朋友来说是极好的。
用一个精彩的回答作为开头:如何入门 Python 爬虫? – 谢科的回答
如果你想学习编程,但是找不到学习路径和资源,欢迎关注专栏:学习编程

第一:爬虫学习系列教程
Python 版本:2.7
整体目录:

一、爬虫入门

二、爬虫实战

三、爬虫利器

四、爬虫进阶

第二(第一的姐妹篇):Python爬虫入门教程
Python 版本:2.7
教程目录:

第三:你已经看完上面(第一或者第二)的教程:再推荐知乎用户@陈唯源 的实战练习博客

第四:最后推荐知乎用户@gaga salamer 的实战练习博客

希望以上的教程可以帮助到大家。

九、微信公众号开发

我的第一个项目就是做的微信公众号机器人,按照当时我的思路来讲讲如何学习使用Python来开发微信公众号:

微信呢公众号功能开发分为两大块:(需要 | 不需要)调用微信内部功能,重点在调用微信内部功能组件。

  1. 需要调用微信内部功能

    需要带哦用微信内部功能组件的比如:公众号收发消息 | 图片、页面分享至朋友圈、用户授权提取用户基本信息、微信小店、微信公众号菜单等内部功能组件,这些功能组件在微信公众号开发者文档里找到:微信公众平台开发者文档

    对于这些功能组件,开发者文档都提供了详细的接口文档,告诉你如何调用,而你只需要用Python调用这些接口即可。比如一个很简单的消息发送的方法

    当然在这所有的调用之前,需要进行一些授权验证,同样开发者文档有一套完整的接入指南:接入指南 – 微信公众平台开发者文档

    很遗憾很多初学者在一开始看这份文档的时候并不能看懂,所以这里也推荐一些我以前学习摸索的过程中使用到的一些简单易学的教程。
    你可以先做一个简单的微信机器人练练手(零基础十分容易上手):

    如果你已经能按照以上的教程搭建一个完整的微信机器人了,基本上对于微信收发消息等等简单功能已经没有什么障碍了。下面再继续学习如下教程,开始学习如何调用其他一些相对来说比较复杂的接口。

    当你实验了如上的教程之后,相信官方文档的所有接口调用对你来说已经小菜一碟了。

  2. 不需要调用微信内部功能

    不需要调用微信内部功能组件的,就如同正常的web页面一样,比如填写表单进行进行注册、点击按钮进行跳转等等,这些都是正常的web请求,按照正常的web开发方法走即可。

十、Python面试概念和代码

https://blog.zhigu34.cn/usr/uploads/sina/5ccb23b626bc8.jpg
(一)、这两个参数是什么意思:args,*kwargs?我们为什么要使用它们?
答:如果我们不确定往一个函数中传入多少参数,或者我们希望以元组(tuple)或者列表(list)的形式传参数的时候,我们可以使用args(单星号)。如果我们不知道往函数中传递多少个关键词参数或者想传入字典的值作为关键词参数的时候我们可以使用*kwargs(双星号),args、kwargs两个标识符是约定俗成的用法。
另一种答法:当函数的参数前面有一个星号号的时候表示这是一个可变的位置参数,两个星号表示这个是一个可变的关键词参数。星号把序列或者集合解包(unpack)成位置参数,两个星号把字典解包成关键词参数。
https://blog.zhigu34.cn/usr/uploads/sina/5ccb23b707204.jpg
(二)、谈一谈Python的装饰器(decorator)
装饰器本质上是一个Python函数,它可以让其它函数在不作任何变动的情况下增加额外功能,装饰器的返回值也是一个函数对象。它经常用于有切面需求的场景。比如:插入日志、性能测试、事务处理、缓存、权限校验等。有了装饰器我们就可以抽离出大量的与函数功能无关的雷同代码进行重用。

有关于具体的装饰器的用法看这里:装饰器 – 廖雪峰的官方网站
https://blog.zhigu34.cn/usr/uploads/sina/5ccb23b7b314f.jpg
(三)、简要描述Python的垃圾回收机制(garbage collection)
Python中的垃圾回收是以引用计数为主,标记-清除和分代收集为辅。
引用计数:Python在内存中存储每个对象的引用计数,如果计数变成0,该对象就会消失,分配给该对象的内存就会释放出来。
标记-清除:一些容器对象,比如list、dict、tuple,instance等可能会出现引用循环,对于这些循环,垃圾回收器会定时回收这些循环(对象之间通过引用(指针)连在一起,构成一个有向图,对象构成这个有向图的节点,而引用关系构成这个有向图的边)。
分代收集:Python把内存根据对象存活时间划分为三代,对象创建之后,垃圾回收器会分配它们所属的代。每个对象都会被分配一个代,而被分配更年轻的代是被优先处理的,因此越晚创建的对象越容易被回收。
如果你想要深入了解Python的GC机制,点击这里:[[转载]Python垃圾回收机制–完美讲解!](https://www.jianshu.com/p/1e375fb40506 “[转载]Python垃圾回收机制–完美讲解!”)

(四)、Python多线程(multi-threading)。这是个好主意吗?
Python并不支持真正意义上的多线程,Python提供了多线程包。Python中有一个叫Global Interpreter Lock(GIL)的东西,它能确保你的代码中永远只有一个线程在执行。经过GIL的处理,会增加执行的开销。这就意味着如果你先要提高代码执行效率,使用threading不是一个明智的选择,当然如果你的代码是IO密集型,多线程可以明显提高效率,相反如果你的代码是CPU密集型的这种情况下多线程大部分是鸡肋。
想要深入详细了解多线程,点击这里:详解Python中的多线程编程_python
想了解一下IO密集和CPU密集可以点击这里:CPU-bound(计算密集型) 和I/O bound(I/O密集型) 和I/O bound(I/O密集型)”)

(五)、 说明os,sys模块不同,并列举常用的模块方法?
官方文档: 
os模板提供了一种方便的使用操作系统函数的方法
sys模板可供访问由解释器使用或维护的变量和与解释器交互的函数
另一种回答:
os模块负责程序与操作系统的交互,提供了访问操作系统底层的接口。sys模块负责程序与Python解释器的交互,提供了一系列的函数和变量用户操作Python运行时的环境。一些常用的方法:
https://blog.zhigu34.cn/usr/uploads/sina/5ccb23b8ada2a.jpg
https://blog.zhigu34.cn/usr/uploads/sina/5ccb23b97e2b2.jpg
一些常用的用法示例:
https://blog.zhigu34.cn/usr/uploads/sina/5ccb23ba2a297.jpg
想要了解更详细的使用请访问:os和sys模块 – 君醉

(六)、什么是lambda表达式?它有什么好处?
简单来说,lambda表达式通常是当你需要使用一个函数,但是又不想费脑袋去命名一个函数的时候使用,也就是通常所说的匿名函数。
lambda表达式一般的形式是:关键词lambda后面紧接一个或多个参数,紧接一个冒号“:”,紧接一个表达式。lambda表达式是一个表达式不是一个语句。
https://blog.zhigu34.cn/usr/uploads/sina/5ccb23ba90b8d.jpg

想更加详细的了解Python中的Lamdba表达式可以点击这里:Lambda 表达式有何用处?如何使用? – Python

(七)、Python中pass语句的作用是什么?
pass语句不会执行任何操作,一般作为占位符或者创建占位程序

(八)、Python是如何进行类型转换的?
Python提供了将变量或值从一种类型转换为另一种类型的内置方法。
https://blog.zhigu34.cn/usr/uploads/sina/5ccb23bb2e73b.jpg

(九)、Python里面如何拷贝一个对象?
Python中对象之间的赋值是按引用传递的,如果要拷贝对象需要使用标准模板中的copy
copy.copy:浅拷贝,只拷贝父对象,不拷贝父对象的子对象。
copy.deepcopy:深拷贝,拷贝父对象和子对象。
https://blog.zhigu34.cn/usr/uploads/sina/5ccb23bbd25d5.jpg

(十)、__new__和__init__的区别。
__init__为初始化方法,__new__方法是真正的构造函数。
__new__是实例创建之前被调用,它的任务是创建并返回该实例,是静态方法
__init__是实例创建之后被调用的,然后设置对象属性的一些初始值。 
总结:__new__方法在__init__方法之前被调用,并且__new__方法的返回值将传递给__init__方法作为第一个参数,最后__init__给这个实例设置一些参数。
https://blog.zhigu34.cn/usr/uploads/sina/5ccb23bc7827e.jpg
想要更加详细的了解这两个方法,请点击:Python中的__new__及其用法

(十一)、Python中单下划线和双下划线分别是什么?
__name__:一种约定,Python内部的名字,用来与用户自定义的名字区分开,防止冲突
_name:一种约定,用来指定变量私有
__name:解释器用_classname__name来代替这个名字用以区别和其他类相同的命名
想要更加详细的了解这两者的区别,请点击:Python中的下划线(译文)

(十二)、说一说Python自省。
自省就是面向对象的语言所写的程序在运行时,所能知道对象的类型。简单一句话就是运行时能够获得对象的类型。比如:type()、dir()、getattr()、hasattr()、isinstance()
https://blog.zhigu34.cn/usr/uploads/sina/5ccb23bd12bb7.jpg
想要完整的理解Python自省,请点击:Python自省(反射)指南
有关于元类以及单例模式会在后面文章中做详细的解释说明。

本文参考文献资料:

十一、Python书籍

入门书籍

  • 《Python学习手册》
  • 《Head First Python》
  • 《Learn Python The Hard Way》
  • 《Python编程:入门到实践》
  • 《笨办法学Python》
  • 《简明Python教程》

进阶书籍

  • 《Python Cookbook(第三版)》
  • 《流畅的Python》
  • 《Python源码剖析》
  • 《Python进阶》
  • 《Flask Web开发:基于Python的Web应用开发实战》
首页      Python      Python | 路人甲的Python总结

古迹年华

Python | 路人甲的Python总结
前言知乎:路人甲微博:玩数据的路人甲微信公众号:一个程序员的日常在知乎分享已经有一年多了,之前一直有朋友说我的回答能整理成书籍了,一直偷懒没做,最近有空仔细整理了知乎上的回答…
扫描二维码继续阅读
2019-03-29