Wednesday, June 8, 2016
Monday, February 8, 2016
Python 爬虫入门
转自知乎
著作权归作者所有。
商业转载请联系作者获得授权,非商业转载请注明出处。
作者:谢科
链接:http://www.zhihu.com/question/20899988/answer/24923424
来源:知乎
商业转载请联系作者获得授权,非商业转载请注明出处。
作者:谢科
链接:http://www.zhihu.com/question/20899988/answer/24923424
来源:知乎
“入门”是良好的动机,但是可能作用缓慢。如果你手里或者脑子里有一个项目,那么实践起来你会被目标驱动,而不会像学习模块一样慢慢学习。
另外如果说知识体系里的每一个知识点是图里的点,依赖关系是边的话,那么这个图一定不是一个有向无环图。因为学习A的经验可以帮助你学习B。因此,你不需要学习怎么样“入门”,因为这样的“入门”点根本不存在!你需要学习的是怎么样做一个比较大的东西,在这个过程中,你会很快地学会需要学会的东西的。当然,你可以争论说需要先懂python,不然怎么学会python做爬虫呢?但是事实上,你完全可以在做这个爬虫的过程中学习python :D
看到前面很多答案都讲的“术”——用什么软件怎么爬,那我就讲讲“道”和“术”吧——爬虫怎么工作以及怎么在python实现。
先长话短说summarize一下:
你需要学习
以下是短话长说:
说说当初写的一个集群爬下整个豆瓣的经验吧。
1)首先你要明白爬虫怎样工作。
想象你是一只蜘蛛,现在你被放到了互联“网”上。那么,你需要把所有的网页都看一遍。怎么办呢?没问题呀,你就随便从某个地方开始,比如说人民日报的首页,这个叫initial pages,用$表示吧。
在人民日报的首页,你看到那个页面引向的各种链接。于是你很开心地从爬到了“国内新闻”那个页面。太好了,这样你就已经爬完了俩页面(首页和国内新闻)!暂且不用管爬下来的页面怎么处理的,你就想象你把这个页面完完整整抄成了个html放到了你身上。
突然你发现, 在国内新闻这个页面上,有一个链接链回“首页”。作为一只聪明的蜘蛛,你肯定知道你不用爬回去的吧,因为你已经看过了啊。所以,你需要用你的脑子,存下你已经看过的页面地址。这样,每次看到一个可能需要爬的新链接,你就先查查你脑子里是不是已经去过这个页面地址。如果去过,那就别去了。
好的,理论上如果所有的页面可以从initial page达到的话,那么可以证明你一定可以爬完所有的网页。
那么在python里怎么实现呢?
很简单
另外如果说知识体系里的每一个知识点是图里的点,依赖关系是边的话,那么这个图一定不是一个有向无环图。因为学习A的经验可以帮助你学习B。因此,你不需要学习怎么样“入门”,因为这样的“入门”点根本不存在!你需要学习的是怎么样做一个比较大的东西,在这个过程中,你会很快地学会需要学会的东西的。当然,你可以争论说需要先懂python,不然怎么学会python做爬虫呢?但是事实上,你完全可以在做这个爬虫的过程中学习python :D
看到前面很多答案都讲的“术”——用什么软件怎么爬,那我就讲讲“道”和“术”吧——爬虫怎么工作以及怎么在python实现。
先长话短说summarize一下:
你需要学习
- 基本的爬虫工作原理
- 基本的http抓取工具,scrapy
- Bloom Filter: Bloom Filters by Example
- 如果需要大规模网页抓取,你需要学习分布式爬虫的概念。其实没那么玄乎,你只要学会怎样维护一个所有集群机器能够有效分享的分布式队列就好。最简单的实现是python-rq: https://github.com/nvie/rq
- rq和Scrapy的结合:darkrho/scrapy-redis · GitHub
- 后续处理,网页析取(grangier/python-goose · GitHub),存储(Mongodb)
以下是短话长说:
说说当初写的一个集群爬下整个豆瓣的经验吧。
1)首先你要明白爬虫怎样工作。
想象你是一只蜘蛛,现在你被放到了互联“网”上。那么,你需要把所有的网页都看一遍。怎么办呢?没问题呀,你就随便从某个地方开始,比如说人民日报的首页,这个叫initial pages,用$表示吧。
在人民日报的首页,你看到那个页面引向的各种链接。于是你很开心地从爬到了“国内新闻”那个页面。太好了,这样你就已经爬完了俩页面(首页和国内新闻)!暂且不用管爬下来的页面怎么处理的,你就想象你把这个页面完完整整抄成了个html放到了你身上。
突然你发现, 在国内新闻这个页面上,有一个链接链回“首页”。作为一只聪明的蜘蛛,你肯定知道你不用爬回去的吧,因为你已经看过了啊。所以,你需要用你的脑子,存下你已经看过的页面地址。这样,每次看到一个可能需要爬的新链接,你就先查查你脑子里是不是已经去过这个页面地址。如果去过,那就别去了。
好的,理论上如果所有的页面可以从initial page达到的话,那么可以证明你一定可以爬完所有的网页。
那么在python里怎么实现呢?
很简单
写得已经很伪代码了。
所有的爬虫的backbone都在这里,下面分析一下为什么爬虫事实上是个非常复杂的东西——搜索引擎公司通常有一整个团队来维护和开发。
2)效率
如果你直接加工一下上面的代码直接运行的话,你需要一整年才能爬下整个豆瓣的内容。更别说Google这样的搜索引擎需要爬下全网的内容了。
问题出在哪呢?需要爬的网页实在太多太多了,而上面的代码太慢太慢了。设想全网有N个网站,那么分析一下判重的复杂度就是N*log(N),因为所有网页要遍历一次,而每次判重用set的话需要log(N)的复杂度。OK,OK,我知道python的set实现是hash——不过这样还是太慢了,至少内存使用效率不高。
通常的判重做法是怎样呢?Bloom Filter. 简单讲它仍然是一种hash的方法,但是它的特点是,它可以使用固定的内存(不随url的数量而增长)以O(1)的效率判定url是否已经在set中。可惜天下没有白吃的午餐,它的唯一问题在于,如果这个url不在set中,BF可以100%确定这个url没有看过。但是如果这个url在set中,它会告诉你:这个url应该已经出现过,不过我有2%的不确定性。注意这里的不确定性在你分配的内存足够大的时候,可以变得很小很少。一个简单的教程:Bloom Filters by Example
注意到这个特点,url如果被看过,那么可能以小概率重复看一看(没关系,多看看不会累死)。但是如果没被看过,一定会被看一下(这个很重要,不然我们就要漏掉一些网页了!)。 [IMPORTANT: 此段有问题,请暂时略过]
好,现在已经接近处理判重最快的方法了。另外一个瓶颈——你只有一台机器。不管你的带宽有多大,只要你的机器下载网页的速度是瓶颈的话,那么你只有加快这个速度。用一台机子不够的话——用很多台吧!当然,我们假设每台机子都已经进了最大的效率——使用多线程(python的话,多进程吧)。
3)集群化抓取
爬取豆瓣的时候,我总共用了100多台机器昼夜不停地运行了一个月。想象如果只用一台机子你就得运行100个月了...
那么,假设你现在有100台机器可以用,怎么用python实现一个分布式的爬取算法呢?
我们把这100台中的99台运算能力较小的机器叫作slave,另外一台较大的机器叫作master,那么回顾上面代码中的url_queue,如果我们能把这个queue放到这台master机器上,所有的slave都可以通过网络跟master联通,每当一个slave完成下载一个网页,就向master请求一个新的网页来抓取。而每次slave新抓到一个网页,就把这个网页上所有的链接送到master的queue里去。同样,bloom filter也放到master上,但是现在master只发送确定没有被访问过的url给slave。Bloom Filter放到master的内存里,而被访问过的url放到运行在master上的Redis里,这样保证所有操作都是O(1)。(至少平摊是O(1),Redis的访问效率见:LINSERT – Redis)
考虑如何用python实现:
在各台slave上装好scrapy,那么各台机子就变成了一台有抓取能力的slave,在master上装好Redis和rq用作分布式队列。
代码于是写成
所有的爬虫的backbone都在这里,下面分析一下为什么爬虫事实上是个非常复杂的东西——搜索引擎公司通常有一整个团队来维护和开发。
2)效率
如果你直接加工一下上面的代码直接运行的话,你需要一整年才能爬下整个豆瓣的内容。更别说Google这样的搜索引擎需要爬下全网的内容了。
问题出在哪呢?需要爬的网页实在太多太多了,而上面的代码太慢太慢了。设想全网有N个网站,那么分析一下判重的复杂度就是N*log(N),因为所有网页要遍历一次,而每次判重用set的话需要log(N)的复杂度。OK,OK,我知道python的set实现是hash——不过这样还是太慢了,至少内存使用效率不高。
通常的判重做法是怎样呢?Bloom Filter. 简单讲它仍然是一种hash的方法,但是它的特点是,它可以使用固定的内存(不随url的数量而增长)以O(1)的效率判定url是否已经在set中。可惜天下没有白吃的午餐,它的唯一问题在于,如果这个url不在set中,BF可以100%确定这个url没有看过。但是如果这个url在set中,它会告诉你:这个url应该已经出现过,不过我有2%的不确定性。注意这里的不确定性在你分配的内存足够大的时候,可以变得很小很少。一个简单的教程:Bloom Filters by Example
注意到这个特点,url如果被看过,那么可能以小概率重复看一看(没关系,多看看不会累死)。但是如果没被看过,一定会被看一下(这个很重要,不然我们就要漏掉一些网页了!)。 [IMPORTANT: 此段有问题,请暂时略过]
好,现在已经接近处理判重最快的方法了。另外一个瓶颈——你只有一台机器。不管你的带宽有多大,只要你的机器下载网页的速度是瓶颈的话,那么你只有加快这个速度。用一台机子不够的话——用很多台吧!当然,我们假设每台机子都已经进了最大的效率——使用多线程(python的话,多进程吧)。
3)集群化抓取
爬取豆瓣的时候,我总共用了100多台机器昼夜不停地运行了一个月。想象如果只用一台机子你就得运行100个月了...
那么,假设你现在有100台机器可以用,怎么用python实现一个分布式的爬取算法呢?
我们把这100台中的99台运算能力较小的机器叫作slave,另外一台较大的机器叫作master,那么回顾上面代码中的url_queue,如果我们能把这个queue放到这台master机器上,所有的slave都可以通过网络跟master联通,每当一个slave完成下载一个网页,就向master请求一个新的网页来抓取。而每次slave新抓到一个网页,就把这个网页上所有的链接送到master的queue里去。同样,bloom filter也放到master上,但是现在master只发送确定没有被访问过的url给slave。Bloom Filter放到master的内存里,而被访问过的url放到运行在master上的Redis里,这样保证所有操作都是O(1)。(至少平摊是O(1),Redis的访问效率见:LINSERT – Redis)
考虑如何用python实现:
在各台slave上装好scrapy,那么各台机子就变成了一台有抓取能力的slave,在master上装好Redis和rq用作分布式队列。
代码于是写成
好的,其实你能想到,有人已经给你写好了你需要的:darkrho/scrapy-redis · GitHub
4)展望及后处理
虽然上面用很多“简单”,但是真正要实现一个商业规模可用的爬虫并不是一件容易的事。上面的代码用来爬一个整体的网站几乎没有太大的问题。
但是如果附加上你需要这些后续处理,比如
如你所想,这里每一个点都可以供很多研究者十数年的研究。虽然如此,
“路漫漫其修远兮,吾将上下而求索”。
所以,不要问怎么入门,直接上路就好了:)
4)展望及后处理
虽然上面用很多“简单”,但是真正要实现一个商业规模可用的爬虫并不是一件容易的事。上面的代码用来爬一个整体的网站几乎没有太大的问题。
但是如果附加上你需要这些后续处理,比如
- 有效地存储(数据库应该怎样安排)
- 有效地判重(这里指网页判重,咱可不想把人民日报和抄袭它的大民日报都爬一遍)
- 有效地信息抽取(比如怎么样抽取出网页上所有的地址抽取出来,“朝阳区奋进路中华道”),搜索引擎通常不需要存储所有的信息,比如图片我存来干嘛...
- 及时更新(预测这个网页多久会更新一次)
如你所想,这里每一个点都可以供很多研究者十数年的研究。虽然如此,
“路漫漫其修远兮,吾将上下而求索”。
所以,不要问怎么入门,直接上路就好了:)
Sunday, February 7, 2016
Three Important Questions to Ask in Interview
1. What project are you doing?
2. What is the challenges?
3. How are you dealing with this challenges?
2. What is the challenges?
3. How are you dealing with this challenges?
Javascript Interview Question
1. What is a prompt box?
2. What is ‘this’ keyword in JavaScript?
3. Explain the working of timers in JavaScript? Also elucidate the drawbacks of using the timer, if any?
4. Which symbol is used for comments in Javascript?
//
5. What is the difference between ViewState and SessionState?
Session State contains information that is pertaining to a specific session (by a particular client/browser/machine) with the server.
It's a way to track what the user is doing on the site.. across multiple pages...amid the statelessness of the Web.
e.g. the contents of a particular user's shopping cart is session data. Cookies can be used for session state.
View State on the other hand is information specific to particular web page.
It is stored in a hidden field so that it isn't visible to the user.
It is used to maintain the user's illusion that the page remembers what he did on it the last time -
dont give him a clean page every time he posts back.
6. What is === operator?
7. Explain how can you submit a form using JavaScript?
<form name="myform" action="handle-data.php">
Search: <input type='text' name='query' />
<a href="javascript: submitform()">Search</a>
</form>
<script type="text/javascript">
function submitform()
{
document.myform.submit();
}
</script>
8. Does JavaScript support automatic type conversion?
9. How can the style/class of an element be changed
document.getElementById("MyElement").className = "MyClass";
10. Explain how to read and write a file using JavaScript?
JS EXT
fopen getscript path
str = fread(file,flength(file) ;
11. What are all the looping structures in JavaScript?
for (i = 0; i < cars.length; i++) {
text += cars[i] + "<br>";
}
12. What is called Variable typing in Javascript?
13 How to use angularJS to receive Json ?
14
2. What is ‘this’ keyword in JavaScript?
3. Explain the working of timers in JavaScript? Also elucidate the drawbacks of using the timer, if any?
4. Which symbol is used for comments in Javascript?
//
5. What is the difference between ViewState and SessionState?
Session State contains information that is pertaining to a specific session (by a particular client/browser/machine) with the server.
It's a way to track what the user is doing on the site.. across multiple pages...amid the statelessness of the Web.
e.g. the contents of a particular user's shopping cart is session data. Cookies can be used for session state.
View State on the other hand is information specific to particular web page.
It is stored in a hidden field so that it isn't visible to the user.
It is used to maintain the user's illusion that the page remembers what he did on it the last time -
dont give him a clean page every time he posts back.
6. What is === operator?
7. Explain how can you submit a form using JavaScript?
<form name="myform" action="handle-data.php">
Search: <input type='text' name='query' />
<a href="javascript: submitform()">Search</a>
</form>
<script type="text/javascript">
function submitform()
{
document.myform.submit();
}
</script>
8. Does JavaScript support automatic type conversion?
9. How can the style/class of an element be changed
document.getElementById("MyElement").className = "MyClass";
10. Explain how to read and write a file using JavaScript?
JS EXT
fopen getscript path
str = fread(file,flength(file) ;
11. What are all the looping structures in JavaScript?
for (i = 0; i < cars.length; i++) {
text += cars[i] + "<br>";
}
12. What is called Variable typing in Javascript?
13 How to use angularJS to receive Json ?
14
Wednesday, February 3, 2016
Thursday, January 28, 2016
Friday, January 22, 2016
J2EE Onsite Skype Interview 2
1. Pass by Value vs Pass by Reference !!!!
2. How to make a immutable class
3. Difference between List Set and Map
4. How to commit code in Git
5. What is the difference between fetch and pull in Git
6. What is difference between snapshot version and release version.
7. How to make a compile time dependency in Maven
8. What is the difference between final finally and finalize?
9. What is static in Java?
2. How to make a immutable class
3. Difference between List Set and Map
4. How to commit code in Git
5. What is the difference between fetch and pull in Git
6. What is difference between snapshot version and release version.
7. How to make a compile time dependency in Maven
8. What is the difference between final finally and finalize?
9. What is static in Java?
Thursday, January 21, 2016
J2EE Onsite Skype Interview 1
Calculate
Total Price Exercise
Accept 3 inputs from the user:
● How many items
● Price per item
● 2-letter state code
Output the total price. Give a discount based on the
total price, add state tax based on the state and the discounted price.
Order Value
|
Discount Rate
|
$1000
|
3%
|
$5000
|
5%
|
$7000
|
7%
|
$10000
|
10%
|
$50000
|
15%
|
State
|
Tax Rate
|
UT
|
6.85%
|
NV
|
8.00%
|
TX
|
6.25%
|
AL
|
4.00%
|
CA
|
8.25%
|
Acceptance
Tests:
First Test
When an item price is 493.87
And an item quantity is 15
And a state is CA
Then the total price is 7,457.87
Second Test
When an item price is 1,493.87
And an item quantity is 825
And a state is UT
Then the total price is 1,119,335.32
Implement Test Driven Development Methodology
Implement Test Driven Development Methodology
- 必须知道什么是TDD以及TDD的Best Practice
- 得分点: 分成两个文件夹Test 和 Java
- 得分点: 先写测试
- 得分点:测试类名必须是XXXTest.java
- 得分点:测试类和被测试类必须在同一个package里面,例如model
- 熟悉JUnit API了解 assertEquals方法如何测试double类型
- 计算折扣的业务逻辑非常容易搞错
- floating point numbers are not perfectly precise
- price 设计成 int 表示美分也是也是一个重要的点
ASD - Agile Software Development
1. 项目分成好几个 Sprint 一个Sprint 大约 2 到 3 周.
2. Project Manager 或者 Team Lead 对一个 Sprint 分成很多个 Story.
3. 一般情况下在某一个周五进行 Sprint Planning. 分析接下来2-3个星期做什么,哪些story可以做,谁来做。
4. 用 RALLY 做 Agile 的开发分配任务等.
5. 一个 Story的难度由一系列Fibonacci数列定义。所有Story加在一起的分数为一个 Sprint 的难度。一般在30几分左右。
6. 每天早上汇报昨天做了什么,今天打算做什么,预计有什么困难?
7. 一个 Story 步骤 Design, Development, Code Review, Unit Test, Functional Test, Debug, Retest, Story 结束
8. 一个 Sprint 开发结束之后需要做 DEMO, DEMO 需要经过stakeholder同意通过。
9. Sprint 开发结束之后要开一个会叫做 Agile Retrospective 总结有哪些做的好或者不好的,学到了什么经验可以用来提高以后的开发效率。
10. 做完所有的Sprint要Smoke Test 看看有没有基本的问题. 之后代码从 Dev 移到 QA.
11. 做Integration Test
12. 做Regression Test 看新的程序对旧的输入有没有影响。
13. 把代码转交给Stake Holder 一方的 QA 做 End To End Testing 和 User Acceptance Testing.
2. Project Manager 或者 Team Lead 对一个 Sprint 分成很多个 Story.
3. 一般情况下在某一个周五进行 Sprint Planning. 分析接下来2-3个星期做什么,哪些story可以做,谁来做。
4. 用 RALLY 做 Agile 的开发分配任务等.
5. 一个 Story的难度由一系列Fibonacci数列定义。所有Story加在一起的分数为一个 Sprint 的难度。一般在30几分左右。
6. 每天早上汇报昨天做了什么,今天打算做什么,预计有什么困难?
7. 一个 Story 步骤 Design, Development, Code Review, Unit Test, Functional Test, Debug, Retest, Story 结束
8. 一个 Sprint 开发结束之后需要做 DEMO, DEMO 需要经过stakeholder同意通过。
9. Sprint 开发结束之后要开一个会叫做 Agile Retrospective 总结有哪些做的好或者不好的,学到了什么经验可以用来提高以后的开发效率。
10. 做完所有的Sprint要Smoke Test 看看有没有基本的问题. 之后代码从 Dev 移到 QA.
11. 做Integration Test
12. 做Regression Test 看新的程序对旧的输入有没有影响。
13. 把代码转交给Stake Holder 一方的 QA 做 End To End Testing 和 User Acceptance Testing.
Sunday, January 17, 2016
Netflix的系统设计
NETFLIX, YOUTUBE和SPOTLIGHT系统设计SNAKE分析 |
|||
宏观角度
|
微观角度
|
||
功
能
分
析
|
罗列功能
对所有功能进行排序
设计最重要的功能:播放电影
|
设计某个小模块
比如电影推荐
设计接口和方法
|
|
限
制
条
件
和
假
设
|
USER
|
·
Daily Active Users
·
Average Concurrent Users
·
Peak Users
·
Max Peak Users in 3 month
|
对方法的调用频率进行计算
计算QPS
计算需要多少server达到所需QPS
|
TRAFFIC
|
·
Traffic per user 3mpbs
·
Max Peak Traffic in 3 month
|
||
MEMORY
|
·
Memory per user 10k
·
Max Daily Memory if double in 3 month
|
||
STORAGE
|
·
Total Number of movies
·
Calculate total storage usage considering
different quality of movies
|
||
应
用
架
构
和
算
法
|
应用设计模式的知识设计系统Service结构 (MVC架构)
|
算法和数据结构
|
|
数
据
层
设
计
|
Model DAO不同文件不同数据库选择 (MySQL 和
MongoDB 以及 File)
|
改进算法和数据结构提高QPS
|
|
系
统
演
化
|
改进效率,扩充性,鲁棒性
|
改进效率,扩充性,鲁棒性
|
|
Saturday, January 16, 2016
程序员能力的评判标准
程序员能力的评判标准
|
|||||
能力
|
LEVEL 1
入门
|
LEVEL 2
深度
|
LEVEL 3
广度
|
LEVEL 4
经验
|
LEVEL 5
预测
|
编程
能力
|
能够完成函数级开发
|
能够完成模块级开发
|
能够完成项目级开发
|
能够作为主程完成大规模系统的开发
|
能够前瞻性的预测研发的走势并作出准备
|
现场写代码
评分标准:
可读
有效
防御
|
多线程:能解决生产者消费者问题
网络:能解决爬虫问题
数据库:能够使用MySQL和NoSQL
调试:发现并能够解决BUG
优化:能在时间和空间维度解决问题
评分标准:
可以举出实例,不需要都会,
至少要在2点上有深度
|
技术调研:介绍调研的案例
代码整合:介绍整合开源内部库的案例
突发问题:介绍解决突发问题的案例
评分标准:
体现项目级别
至少在2点上有特色
|
介绍你作为主程最具挑战的一个项目。
评分标准:
案例支持技术点
强调整体的把控能力
|
作为项目的主程,你下一步会怎么做?
|
|
设计
能力
|
通过算法和数据结构解决问题
|
能够设计基本的系统
|
能够设计大规模分布式系统
|
参与真实的系统设计并贡献重要力量
|
能够前瞻性的预测架构的走势并进行准备
|
字符串处理算法题
|
用面向对象方法设计消息系统
|
设计日活跃用户1000万的消息系统
|
介绍你参与的最复杂的架构设计。
有哪些经验和改进的思路?
|
作为首席架构师,你下一步会做什么?
|
|
理解
学习
能力
|
能够快速抓住对方沟通的重点
|
能主动学习需要掌握的技能
|
从更大的维度补充需要的知识
|
具有钻研突破难题的经验
|
有清晰的职业规划
|
能否一遍听懂面试官的问题
|
你进入上家公司的时候是如何上手的
|
你在上家公司有哪些提升,是如何提升的?
|
你在上家公司遇到了哪些挑战?
是怎么解决的?
如果重新来一次,有什么更好的方案?
|
你的职业规划是什么?
你希望提升的方向是什么?
为什么来我们公司?
|
|
总结
表达
教学
能力
|
能够用简约的话表达重点
|
能够把自己的知识教给身边的人
|
能从对方的角度讲问题(跨专业)
|
具有对公共分享的经验
|
沟通前瞻性,
能够预知对方的需求和疑问点,
并且主动进行沟通
|
介绍自己你的亮点和需要提高的地方
|
你是如何带新人的?
如何让他们融入团队?
|
如何解决意见不一致?
挑战别人的答案。
|
在公司和部门分享案列
|
自己能够通过直觉感知。
|
|
|
SCORE
|
LEVEL
|
ALI
|
BAIDU
|
TENCENT
|
|
8-9
|
L1
|
P5
|
T4
|
T1.2-T2.2
|
|
10-13
|
L2
|
P6
|
T5
|
T2.2-T3.1
|
|
14+
|
L3+
|
P7+
|
T6+
|
T3.1-T3.2
|
Subscribe to:
Comments (Atom)