python爬虫基础概念

1.什么是爬虫?网页爬取的流程是怎么样的?

爬虫(又被称为网页蜘蛛,网络机器人)就是模拟客户端发送网络请求,接收请求响应,一种按照一定的规则,
自动地抓取互联网信息的程序。原则上,只要浏览器展示出来的数据,爬虫都可以拿的到。

爬虫一般的主要流程为:构建url、发送请求获取响应、提取数据和数据入库等操作。大体如下图所示:

2.python 爬虫有哪些常用第三方库,分别用在哪些环节?

urllib,urllib2、requests都可以用来做数据的抓取,只不过urllib,urllib2是Python2里面的库,
现在很少用到。目前大多数使用Pytho3的requests库。

Beautiful Soup、Xpath都是用来对请求的响应字符串进行格式化提取。


3.说一下什么是url?

   url即统一资源定位符,也就是我们说的请求网址,
统一资源定位符是对可以从互联网上得到的资源的位置和访问方法的一种简洁的表示,
是互联网上标准资源的地址。互联网上的每个文件都有一个唯一的 URL,
它包含的信息指出文件的位置以及浏览器应该怎么处理它。


4.在数据抓取的过程中的GET与POST 方法有什么区别?

1、GET 请求,请求的数据会附加在 URL 之后,以?分割 URL 和传输数据,多个参数用&连接。
    URL 的编码格式采用的是 ASCII 编码,而不是 unicode,
即是说所有的非 ASCII 字符都要编码之后再传输。
POST请求:POST请求会把请求的数据放置在HTTP请求包的包体中。
上面的 item=bandsaw 就是实际的传输数据。因此,GET 请求的数据会暴露在地址栏中,
而 POST 请求则不会。

2、传输数据的大小
    在 HTTP 规范中,没有对 URL 的长度和传输的数据大小进行限制。但是在实际开发过程中,
对于 GET,特定的浏览器和服务器对 URL 的长度有限制。因此,在使用 GET 请求时,
传输数据会受到 URL 长度的限制。对于 POST,由于不是 URL 传值,理论上是不会受限制的,
但是实际上各个服务器会规定对 POST 提交数据大小进行限制。Apache、IIS都有各自的配置。

3、安全性
    POST 的安全性比 GET 的高。这里的安全是指真正的安全,
而不同于上面 GET 提到的安全方法中的安全,上面提到的安全仅仅是不修改服务器的数据。
比如,在进行登录操作,通过 GET 请求,用户名和密码都会暴露再 URL 上,
因为登录页面有可能被浏览器缓存以及其他人查看浏览器的历史记录的原因,
此时的用户名和密码就很容易被他人拿到了。除此之外,GET 请求提交的数据还可能会造成 Cross-site request frogery 攻击。


5.请求的过程中,为什么会有三次握手和四次挥手?

   建立连接的过程是利用客户服务器模式,假设主机 A 为客户端,主机 B 为服务器端。

<1>.TCP 的三次握手过程:主机 A 向 B 发送连接请求;主机 B 对
收到的主机 A 的报文段进行确认;主机 A 再次对主机 B 的确认进行确
认。
<2>.采用三次握手是为了防止失效的连接请求报文段突然又传送到主机 B,因而产生错误。
失效的连接请求报文段是指:主机 A 发出的连接请求没有收到主机 B 的确认,于是经过一段时间后,
主机 A 又重新向主机 B 发送连接请求,且建立成功,顺序完成数据传输。
考虑这样一种特殊情况,主机 A 第一次发送的连接请求并没有丢失,
而是因为网络节点导致延迟达到主机 B,主机 B 以为是主机 A 又发起的新连接,
于是主机 B 同意连接,并向主机 A 发回确认,但是此时主机 A根本不会理会,
主机 B 就一直在等待主机 A 发送数据,导致主机 B 的资源浪费。
<3>采用两次握手不行,原因就是上面说的失效的连接请求的特殊情况,因此采用三次握手刚刚好,
两次可能出现失效,四次甚至更多次则没必要,反而复杂了

四次挥手:
先由客户端向服务器端发送一个 FIN,请求关闭数据传输。当服务器接收到客户端的 FIN 时,
向客户端发送一个 ACK,其中 ack 的值等于 FIN+SEQ然后服务器向客户端发送一个 FIN,
告诉客户端应用程序关闭。当客户端收到服务器端的 FIN 是,回复一个 ACK 给服务器端。
其中 ack 的值等于 FIN+SEQ。

4 次挥是为了确保数据能够完成传输


6.写爬虫是用多进程好?还是多线程好?为什么?

答:IO 密集型代码(文件处理、网络爬虫等),多线程能够有效提升效率(单线程下有 IO 操作会进行 IO 等待,
造成不必要的时间浪费,而开启多线程能在线程 A 等待时,自动切换到线程 B,
可以不浪费 CPU 的资源,从而能提升程序执行效率)。在实际的数据采集过程中,
既考虑网速和响应的问题,也需要考虑自身机器的硬件情况,来设置多进程或多线程。


7.谈一谈你对 Selenium 和 PhantomJS 了解

Selenium 是一个 Web 的自动化测试工具,可以根据我们的指令,
让浏览器自动加载页面,获取需要的数据,甚至页面截屏,或者判断网站上某些动作是否发生。
Selenium 自己不带浏览器,不支持浏览器的功能,它需要与第三方浏览器结合在一起才能使用。
但是我们有时候需要让它内嵌在代码中运行,
所以我们可以用一个叫 PhantomJS的工具代替真实的浏览器。Selenium 库里有个叫 WebDriver 的 API。
WebDriver 有点儿像可以加载网站的浏览器,
但是它也可以像BeautifulSoup 或者其他 Selector 对象一样用来查找页面元素,
与页面上的元素进行交互 (发送文本、点击等),以及执行其他动作来运行网络爬虫。

PhantomJS 是一个基于 Webkit 的“无界面”(headless)浏览器,
它会把网站加载到内存并执行页面上的 JavaScript,因为不会展示图形界面,
所以运行起来比完整的浏览器要高效。

如果我们把 Selenium 和 PhantomJS 结合在一起,就可以运行一个非常强大的网络爬虫了,
这个爬虫可以处理 JavaScrip、Cookie、headers,以及任何我们真实用户需要做的事情。


8.常见的反爬虫和应对方法?

1).通过 Headers 反爬虫
从用户请求的 Headers 反爬虫是最常见的反爬虫策略。
很多网站都会对 Headers 的 User-Agent 进行检测,
还有一部分网站会对 Referer进行检测(一些资源网站的防盗链就是检测 Referer)。
如果遇到了这类反爬虫机制,可以直接在爬虫中添加 Headers,
将浏览器的User-Agent 复制到爬虫的 Headers 中;或者将 Referer 值修改为目标网站域名。
对于检测 Headers 的反爬虫,在爬虫中修改或者添加Headers 就能很好的绕过。

2).基于用户行为反爬虫
还有一部分网站是通过检测用户行为,例如同一 IP 短时间内多次访问同一页面,
或者同一账户短时间内多次进行相同操作。大多数网站都是前一种情况,对于这种情况,
使用 IP 代理就可以解决。可以专门写一个爬虫,爬取网上公开的代理 ip,检测后全部保存起来。
这样的代理 ip 爬虫经常会用到,最好自己准备一个。有了大量代理 ip 后可以每请求几次更换一个 ip,
这在 requests 或者urllib2 中很容易做到,这样就能很容易的绕过第一种反爬虫。
对于第二种情况,可以在每次请求后随机间隔几秒再进行下一次请求。有些有逻辑漏洞的网站,
可以通过请求几次,退出登录,重新登录,继续请求来绕过同一账号短时间内不能多次进行相同请求的限制。

3).动态页面的反爬虫
上述的几种情况大多都是出现在静态页面,还有一部分网站,我们需要爬取的数据是通过ajax请求得到,
或者通过JavaScript生成的。首先用 Fiddler 对网络请求进行分析。如果能够找到 ajax 请求,
也能分析出具体的参数和响应的具体含义,我们就能采用上面的方法,
直接利用 requests 或者 urllib2 模拟 ajax 请求,对响应的 json 进行分析得到需要的数据。
能够直接模拟 ajax 请求获取数据固然是极好的,但是有些网站把ajax 请求的所有参数全部加密了。
我们根本没办法构造自己所需要的数据的请求。这种情况下就用 selenium+phantomJS,
调用浏览器内核,
并利用 phantomJS 执行 js 来模拟人为操作以及触发页面中的js 脚本。
从填写表单到点击按钮再到滚动页面,全部都可以模拟,不考虑具体的请求和响应过程,
只是完完整整的把人浏览页面获取数据的过程模拟一遍。

用这套框架几乎能绕过大多数的反爬虫,因为它不是在伪装成浏览器来获取数据
(上述的通过添加 Headers 一定程度上就是为了伪装成浏览器),它本身就是浏览器,
phantomJS 就是一个没有界面的浏览器,只是操控这个浏览器的不是人。
利 selenium+phantomJS 能干很多事情,例如识别点触式(12306)或者滑动式的验证码,
对页面表单进行暴力破解等。

9.简单说一下你对 scrapy 的了解

scrapy 是一个快速(fast)、高层次(high-level)的基于 python 的 web 爬虫构架。
用来下载、并解析 web 页面, 其 parse->yield item->pipeline 流程是所有爬虫的固有模式。
构造形式主要分pypipeline.py、item.py decorator.py、middlewares.py、setting.py。

 

10.scrapy 和 request之前的区别?

scrapy 是封装起来的框架,他包含了下载器,解析器,日志及异常处理,基于多线程, 
twisted 的方式处理,对于固定单个网站的爬取开发,有优势,但是对于多网站爬取 100 个网站,
并发及分布式处理方面,不够灵活,不便调整与括展。

request 是一个 HTTP 库, 它只是用来,进行请求,对于 HTTP 请求,
他是一个强大的库,下载,解析全部自己处理,灵活性更高,高并发与分布式部署也非常灵活,对于功能可以更好实现.

参考:Python爬虫面试题 

发布了114 篇原创文章 · 获赞 47 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/Jmayday/article/details/104019713