爬虫面试题
1. http 基于 tcp/ip 协议
2. 百度是通用性爬虫
3. http 返回的状态码代表成功的是 200
4. 网页编码使用的函数式 encode()
5. 解码使用的函数式是 decode()
6. 爬虫又叫 网页蜘蛛、网络机器人
7. 什么是爬虫并解释其概念?
(1) 爬虫又叫网页蜘蛛,是模拟人操作客户端向服务器发起请求,抓取数据的自动化程序或脚本
(2) 说明:
① 模拟:用爬虫程序伪装出人的行为,避免被服务器识别为爬虫程序
② 客户端:浏览器、app 都可以实现人与服务器之间的交互行为,应用客户端从服务器获取数据
③ 自动化:数据量较小可以人工获取,但往往在公司里爬取的数据量在百万条、千万条级别,所以要程序自动化获取数据
8. http 协议与 https 协议的区别
1. http 协议需要到 ca 申请证书,一般免费证书较少,因而需要一定费用
2. http 是超文本传输协议,信息是明文传输,https 则是具有安全性的 ssl加密传输协议
3. http 和 https 使用的是完全不同的连接方式,用的端口不一样,前者是 80,后者是 443
4. http 的连接很简单,是无状态的,https 协议是有 ssl +http 协议构建的可进行加密传输、身份认证的网络协议,比 http 协议安全
9. 谈谈你对 tcp 协议与 udp 协议的理解
(1) 两者都是传输层协议
(2) Tcp 协议,是一种面向连接的,可靠的,基于字节流的传输层通信协议,其具有以下 4 个特性:
① 有序性
② 正确性
③ 可靠性
④ 可控性
(3) Udp 协议,是用户数据协议,面向无连接的传输层协议,传输不可靠,其具有以下 3 个特点:
① 无链接,数据可能丢失或损坏
② 报文小,传输速度快
③ 吞吐量大的网络传输,可以在一定程度上承受数据丢失
10. 什么是 robots 协议?阐述 robots 协议与 爬虫的关系?
(1) Robots 协议是 约定哪些内容允许哪些爬虫抓取
(2) 通用爬虫无需遵守 robots 协议,而我们写的聚焦爬虫则需要遵守
11. 网页编码有 utf-8、gbk、gb2312
12. 默认端口信息:
(1) Mysql:3306
(2) Ssh:22
(3) MongoDB:27017
(4) Redis:6379
(5) https:443
(6) http:80
13. Requests 模块发送 get 请求的参数:
(1) Url
(2) Headers
(3) Params
(4) Proxies
14. Requests 模块发送 post 请求的参数:
(1) Url
(2) Headers
(3) Data
(4) Proxies
15. 简述聚焦爬虫的设计思路
(1) 确定 url,模拟浏览器向服务器发送请求
(2) 获取响应数据并进行数据解析
(3) 将目标数据持久化到本地
16. 简述爬虫的分类及各类爬虫的概念
(1) 通用爬虫:爬取网页数据,为搜索引擎提供检索服务
(2) 聚焦爬虫:针对某一领域爬取特定数据的爬虫
① 聚焦爬虫又分为深度爬虫和增量式爬虫
17. 请写出 8 中常用的请求方法
(1) Get
(2) Post
(3) Put
(4) Delete
(5) Trace
(6) Head
(7) Connect
(8) Options
18. 列举反爬虫机制(至少 8 种)
(1) UA 检测
(2) Robots 协议
(3) 验证码
(4) IP 封禁
(5) 账号封禁
(6) 动态数据加载
(7) Js 数据加密
(8) 隐藏参数
(9) 字体反爬
19. Requests 发送请求时携带 headers 参数及作用(至少写 3 点)
User-Agent:实现 UA 伪装
Cookie:模拟登陆
Connection:保持连接
Accept:接受数据类型
20. Requests 向服务器发送文件时,文件的打开模式为 wb
21. Requests 模块那个类自动封装 cookie : session
22. 前端页面由 html、css、JavaScript 等三部分组成
23. 请列举三个可以实现网页请求的库
(1) Requests (2) Urllib (3) Aiohttp
24. 简述 html、css、JavaScript 的作用
(1) Html:定义网页骨架
(2) Css:定义网页样式
(3) JavaScript:定义网页行为
25. 针对 requests 请求的响应对象,如何获取其文本形式,二进制形式及 json数据
(1) Res.text:获取 html 源码
(2) Res.content:获取二进制流,多用于图片、视频下载等
(3) Res.json():获取 json 数据,多用 ajax 请求
26. 请列举三种数据持久化的方式
(1) Csv
(2) Json
(3) Mysql
(4) Mongodb
(5) Redis
27. 正则元字符中“.”代表 匹配 任意字符,换行符除外
28. Responose.text,response.content,res.json 分别获取响应数据的什么形式
(1) Response.text:文本形式
(2) Response.json():json 数据
(3) Response.content:二进制形式
29. 正则表达式中 (.*) 和 (.*?) 匹配区别
(1) (.*):贪婪匹配,尽可能多的匹配
(2) (.*?):非贪婪匹配,尽可能少的匹配
30. Re 模块常用的三个匹配方法,并简述其特点
(1) Re.findall():以列表形式返回所有满足条件的对象
(2) Re.search():匹配到第一个就返回一个对象 ,用 group()取值,匹配不到返回 None
(3) Re.match():从字符串开头匹配,匹配返回一个对象,用 group()取值,匹配不到返回 None
31. Xpath 中根据索引定位节点数时,索引从 1 开始
32. Xpath 中的 contains()函数的第一个参数是 @属性名 ,第二个参数是属性包含的值
33. 请简述单属性多值匹配,多属性匹配概念及使用到的函数或关键字
(1) 单属性多值匹配:根据节点某属性包含的某个值进行定位,使用contains 函数
(2) 多属性匹配:根据节点的多个属性,共同定位该节点,使用关键字 and
34. 请列举爬虫中解析数据的模块(至少三种)
(1) Lxml
(2) Bs4
(3) Pyquery
35. Cookie 和 session 的区别
(1) 数据存储位置不同,cookie 存在客户端,session 存在服务器
(2) 安全程度不同,cookie 存客户端本地,分析 cookie,实现 cookie 欺骗,考虑到安全性,所以用 session
(3) 性能不同,session 存服务器,访问量大时,会增加服务器负载,考虑到性能,所以用 cookie
(4) 数据存储大小不同,单个 cookie 不超过 4k,部分浏览器会限制 cookie的存储个数,但 session 存在服务器,故不受客户端浏览器限制
36. 将 dict 转成 json 串,用 json 模块的函数是 json.dumps()
37. Json.dumps 的参数 ensure_ascii 的作用 避免中文乱码
38. Xpath 如何定位节点的基本语法(至少写三点)
(1) 根据节点名定位:nodename
(2) 根据节点属性定位:nodename[@attribute=”value”]
(3) 从当前节点的根节点向下匹配: ./
(4) 从当前节点的任意位置向下匹配: .//
39. 请描述 xpath 表达式中的./div[@id=”name”]和.//div[@id=”name”]的含义
(1) 从当前节点的根节点向下匹配,匹配一个 div 标签,该 div 标签的 id 属
性值是“name”
(2) 从当前节点的任意位置向下匹配,匹配一个 div 标签,该 div 标签的 id
属性值是“name”
40. 请写出 xpath 表达式中的/text()与//text()的区别
(1) /text():获取已定位节点的直接子文本
(2) //text():获取已定节点的子孙节点文本
41. 请写出 tcp/udp 协议,ip 协议,arp 协议,http/https 协议及 ftp 协议分别位
于 tcp/ip 五层模型的哪一层
(1) TCP/UDP 协议:传输层
(2) IP:网络层
(3) ARP 协议:数据链路层
(4) HTTP/HTTPS:应用层
(5) FTP 协议:应用层
42. 请画出 tcp/ip 五层模型
(1) 应用层
(2) 传输层
(3) 网络层
(4) 数据链路层
(5) 物理层
43. 谈谈 tcp 三次握手四次挥手中为什么要三次握手
(1) TCP 连接的三次握手是为了建立可靠的连接
(2) 第一次握手:客户端向服务器发送 SYN 包,并进入 SYN_SENF 状态,等待服务器确认
(3) 第二次握手:服务器收到 SYN 包,确认并发送 SYN+ACK 包,同时进入 SYN_RECV 状态
(4) 第三次握手:客户端收到服务器 SYN+ACK 包,向服务器确认 ACK 包,进入 ESTABLISHED 状态
44. 请写出 ftp 协议,ssh 协议、mysql、MongoDB、redis 等协议或软件的默
认端口号
(1) ftp:21
(2) Ssh:22
(3) Mysql:3306
(4) Mongodb:27017
(5) Redis:6379
45. 请列举三个第三方提取数据的 Python 库
(1) Wxpython
(2) Py2exe
(3) Psyco
(4) Mysqldb
(5) pyprocessing
46. Bs4 的三种选择器是什么:节点选择器、方法选择器、css 选择器
47. Beautifulsoup 使用步骤
From bs4 import BeautifulSoup
Soup = BeautifulSoup(res.text,’lxml’)
Soup.select(‘css 选择器’)
48. 请简述 bs4 和 lxml 的区别
(1) bs4 会将整个文档树进行加载然后进行查询匹配操作,使用过程中消耗资源较多
(2) lxml 是 python 的一个解析库,支持 HTML 和 XML 的解析,支持 XPath解析方式,而且解析效率非常高,功能更强大
49. 请简述 bs4 中 get_text()和 string 的区别
(1) String:获取节点的直接子文本
(2) get_text():获取节点下子孙节点文本
50. Bs4 对定位到的标签如何获取其直接文本,子孙节点文本和属性
(1) 直接子文本:string
(2) 子孙节点文本:get_text()
(3) 属性:tag[“attribute”]
51. Selenium 使用 execute_script(js) 执行 JS 代码
52. 根据 name 属性查找网页标签使用 find_element_by_name 方法
53. 请列举至少四种 selenium 的交互操作
(1) Clear()
(2) Click()
(3) Send_keys()
(4) Double_click()
54. 列举 selenium 至少四种定位页面元素的方式
(1) Find_element_by_name
(2) Find_element_by_id
(3) Find_element_by_xpath
(4) Find_element_css_selector
55. 假如实例化的浏览器对象名为 broswer,请写出该对象打开百度首页的代码以及获取百度首页源码的代码
From selenium import webdriver
Borwser = webdriver.chrome(“dirverpath”)
Borwser.get(“http://www.baidu.com”)
Html = browser.page_source
56. Mongodb 查看当前工作的数据库的命令是 db
57. Mongodb 查看所有的非空数据库的命令是 show dbs
58. Show dbs 命令无法查看 空 数据库
59. 请写出 mongo db 数据的相关命令
创建并使用集合:use xxx
查看当前工作的集合: db
查看所有非空集合: show dbs
查看当前集合的所有数据:db.table.find()
60. 请列举三种关系型数据库与两种菲关系型数据库
(1) 关系型数据库:Mysql、orcale、sql_server
(2) 非关系数据库:redis、mongodb
61. Mongodb 数据库的优点
(1) 模式自由,面向集合存储,项目增删字段不影响程序运行
(2) 具有丰富的查询表达式,支持动态查询,以满足项目的数据查询需求
(3) 良好的索引支持,文档内嵌对象和数组,均可创建索引
(4) 支持二进制数据存储,可以将图片视频等文件转换为二进制流存储起来
(5)以内存映射为存储引擎,大幅度提升性能
62. 请解释以下操作符的含义:
(1) $gt: >
(2) $lt: <
(3) $gte: >=
(4) $lte: <=
(5) $ne: ≠
(6)$in: 在其中
(7) $nin: 不在其中
(8) $or: 或
63. 向 queue 队列中添加元素操作为 queue.put()
64. 从 queue 队列获取元素的操作为 queue.get()
65. 多线程爬虫共封装了几个类?每个类的作用是什么
(1) 两个类:爬虫类、解析类
(2) 爬虫类;定义爬取的行为,将响应数据提交给响应数据队列
(2) 解析类:定义数据解析规则并与数据库交互,将数据持久化进数据库
66. 谈谈你对进程与线程的理解
(1) 进程是操作系统将资源分配的基本单位,而线程是任务调度执行的基本单位
(2) 线程是进程的一部分,一个线程只能属于一个进程,而一个进程可以有多个线程,但至少要有一个线程
(2) 进程都有独立的代码和数据空间,切换开销大,而线程共享代码与数据空间,切换开销小
67. 请创建一个名为 dataqueueu 的队列,并向其中添加一个字符串 s=’helloqueue’的代码
From queue import Queue
Q = Queue()
S = “hello queue”
Q.put(s)
68. 请简单绘制多线程爬虫的架构原理图
Urlqueue----->爬虫线程------>Internet----->DataQueue------>解析线程------->database
69. 简述什么是 i/o 密集型和计算密集型
(1) Io 密集型是指程序运行时,大部分状况是 CPU 在等待 i/o,即磁盘读写,其特点是程序达到性能极限时,CPU 占用率依然很低,涉及到网络,磁盘 ID 的任务都是 io 密集型
(2) 计算密集型,又称 CPU 密集型,即程序运行过程中,IO 操作很短时间内完成,而 CPU 占用很大,有许多运算要处理,其特点是要进行大量的运算,消耗 CPU 资源
70. 创建一个 scrapy 项目的命令是 scrapy startproject projectname
71. Scrapy 项目运行的命令是 scrapy crawl spidername
72. Scrapy 框架创建爬虫文件的命令为 scrapy genspider spidernamedomain
73. 简述 scrapy 五大核心组件及作用
(1) 引擎:负责各个组件之间的通讯信号及数据的传递
(2) 爬虫:定义了爬取行为和解析规则,提交 item 并传给管道
(3) 调度器:接受引擎传递的 request,并整理排列,然后进行请求的调度
(4) 下载器:负责下载 request,提交响应给引擎,引擎传递给 spider
(5) 管道: 负责处理 spider 传递来 的 item,如 去重、持久化存储等
74. Scrapy 框架有哪些优点
(1) 框架封装的组件丰富,适用于开发大规模的抓取项目
(2) 框架基于 Twisted 异步框架,异步处理请求,更快捷,更高效
(3) 拥有强大的社区支持,拥有丰富的插件来扩展其功能
75. Scrapy 基于 Twisted 异步 框架
76. Allowed_domains 的作用是 限制爬虫爬取的范围
77. 请简述 scrapy 框架五大核心组件有哪些
(1) 引擎
(2) 爬虫
(3) 调度器
(4) 下载器
(5) 管道
78. 如何判断 scrapy 管道类是否需要 return item
(1)在 scrapy 框架中,可以自定义多个管道类,以满足不同的数据持久化需求,当定义多管理类时,多个管道需传递 item 来进行存储,管道类
各有自己的权重,权重越小,我们认为越接近引擎,越先接受引擎传递来的 item 进行存储, 故欲使权重大的管道能够接受到 item,前一个管
道必须 return item,如果一个管道类后无其他管道类,该管道则无需return item
79. 请问为什么下载器返回的相应数据不是直接通过引擎传递给管道,而是传递给 spider
(2) 由于在 scrapy 中,spider 不但定义了爬取的行为,还定义了数据解析规则,所以响应数据需传递给 spider 进行数据解析后,才能将目标数
据传递给管道,进行持久化存储
80. 在 scrapy 框架中手动发起请求时,使用 meta 参数给解析方法传递数据
81. Scrapy 框架发送 post 请求使用 FormRequest 方法
82. 请简述scrapy阻止对start_urls内url主动发送请求时重写的父类方法名称,及使用 scrapy.request 的常用参数及含义
(1) 父类方法名称:start_requests
(2) 参数:
② Url------>发送请求
③ Callback----->指定回调,解析方法
83. 简述详情页爬取的思路
(1) 访问列表页
(2) 从列表页的响应数据中获取详情页 url
(3) 请求详情页 url,使用 scrapy.request 手动发送请求并指定回调
(4) 解析数据在回调中获取目标数据
84. 简述多页爬取的思路
(1) 思路一:将所有的页面 url 生成后放在 start_urls 中,当项目启动后会对 start_urls 中的 url 发起请求,实现多页爬取
(2) 思路二:在解析方法中构建 url,使用 scrapy 手动发送请求并指定回调,实现多页爬取
85. 安装 scrapy 框架的命令为 pip install scrapy
86. Scrapy 框架管道必须实现的方法是 process_item
87. 请使用 fake_useragent 模块实现一个简单的 ua 池
from fake_useragent import UserAgent
Ua_obj = UserAgent()
Ua_pool = [ ]
For i in range(50):
Ua = ua_obj.chrome
Ua_pool.append(ua)
f fr ro om m fake_useragent i i mp po or rt t UserAgent
ua = UserAgent()
ua_pool = []
f fo or r i i in n range(50):
user_agent = ua.Chrome
ua_pool.append(user_agent)
d de ef f process_request(self, request, spider):
request.headers[' 'U Us se er r- -A Ag ge en nt t' '] = random.choice(ua_pool)
r re et tu ur rn n N No on ne e
c cl la as ss s UaSpider(scrapy.Spider):
name = ' 'u ua a' '
# allowed_domains = ['baidu.com']
start_urls = [' 'h ht tt tp p: :/ // /b ba ai id du u. .c co o m/ /' ' f fo or r i i in n range(10)]
d de ef f parse(self, response):
p pa as ss s
88. Scrapy 框架中间件的分类及其作用
(1) 下载中间件:拦截请求与响应,用于篡改响应
(2) 爬虫中间件:除下载中间件的作用以外,还可以实现 item 丢弃
89. Scrapy 框架下载中间件的核心方法及其作用
(1) Process_request:拦截非异常请求
(2) Process_response:拦截所有响应
(3) Process_exception:拦截异常请求
90. 修改 scrapy 项目的配置需要修改 settings 文件
91. 应用 selenium 框架实例化浏览器对象时,使用 executable_path 参数指定驱动路径
92. 动态数据加载的两种情况及相应的解决方案
(1) ajax 请求
① 方案:如果 url 有规律,直接构建 url 实现请求,如果 url 无规律,则用 selenium
(2) Js 动态数据加载
① 方案:可以采用 scrapy 框架与 selenium 框架对接,实现动态数据加载
93. 简述 selenium 与 scrapy 框架对接实现动态加载数据的爬取思路
(1) 在 scrapy 项目中正常对动态加载的页面发起请求,在下载中间件中拦截动态加载页面的响应数据,在process_response方法中,
调用selenium抓取相应的 url,获取 html 源码后再替换原有响应
94. 请写出 selenium 的常用节点交互操作(至少 5 条)
(1) Clear():清空
(2) send_keys():输入
(3) Click():点击
(4) Quit():退出
(5) double_click():双击
95. 创建基于 crawl 的全站爬虫的命令
(1) Scrapy startproject projectnameScrapy genspider -t crawl spidername baidu.com
96. 简述 pipeline 的核心方法及各方法实现什么功能
(1) From_crauler:它是一个类方法,用@classmethod 装饰,用于获取项目的配置
(2) Open_spider:在爬虫开启时被调用,可在其中连接数据库
(3) process_item:在该方法中实现与数据库的交互,存储数据
(4) close_spider:在爬虫关闭时调用,可在其中关闭数据库连接
97. Scrapy 原生框架实现分布式要依赖哪个组件?该组件解决了什么问题
(1) scrapy_redis 组件
(2) 该组件为分布式提供了共享的管道和共享的调度器
98. 列举三种常用的网络数据爬取的模块或框架
(1) Requests
(2) Scrapy
(3) Urllib
(4) Aiohttp
(5) Pyspider
99. 请谈谈动态数据加载的爬取思路
(1) 在 scrapy 项目中正常对动态加载的页面发起请求,在下载中间件中拦截动态加载页面的响应数据,在process_response方法中,调用selenium
抓取相应的 url,获取 html 源码后再替换原有响应
100. 请列举 5 种反爬机制及其对应的反反爬 策略
(1) Ua 检测:ua 伪装
(2) Robots 协 议 : requests 模 块 无 须 理 会 , settings 配 置 中 将ROBOTSTXT_OBEY 改为 False
(3) 动态数据加载:selenium 抓取
(4) 图片懒加载:根据响应数据获取实际的 src 属性值
(5) Ip 封禁:使用代理 ip
101. 请详细阐述如何在下载中间件中篡改请求头信息,代理 ip
(1) 在下载中间件的 process_request 中加入如下代码:
① Reuqest.meta[“proxy”] = “http://ip:port” # 实现代理 ip
② Request.header[“User-Agent”] = “ ” # 实现 ua 伪装
102. 请写出爬虫 数据持久化 Python 与 mongodb 数据库的交互编码
Import pymongo
Class SpiderPipline(object):
Conn = pymongo.MongoClient()
Db = conn.xxx
Table = db.xx
Def process_item(self,item,spider):
Self.table.insert_one(dict(item))
Return item