最近准备试试外面的市场,找找看外面的岗位,给自己找点后路,防止到时候被裁被动。
我将面试题分为基于scrapy框架与普通爬虫【requests/aiohttp等开发的爬虫】
普通爬虫面试题
列举反爬虫机制
(1) UA 检测,请求头合法性
(2) Robots 协议
(3) 验证码
(4) IP 封禁
(5) 账号封禁
(6) 动态数据加载
(7) 请求参数加密/响应结果加密
(8) 隐藏参数
(9) 字体反爬
针对 requests 请求的响应对象,如何获取其文本形式,二进制形式及 json数据?
# 获取文本形式的响应内容
text_content = response.text# 获取二进制形式的响应内容
binary_content = response.content# 获取JSON数据
json_data = response.json()
文本形式(Text):
适用场景: 当你处理的是文本数据,比如HTML网页内容、纯文本文件等时,可以使用.text属性获取文本形式的响应。
示例应用: 网页爬取、文本数据分析、日志文件读取等。
二进制形式(Binary):
适用场景: 当你处理的是二进制数据,比如图片、音频、视频文件等时,可以使用.content属性获取二进制形式的响应。
示例应用: 下载文件、处理图像数据、处理音频或视频数据等。
JSON数据:
适用场景: 当你请求的资源返回的是JSON格式的数据时,使用.json()方法能够方便地将JSON数据解析为Python字典或列表。
示例应用: 与API交互、处理前端通过AJAX请求返回的数据、处理包含结构化信息的数据等。
正则表达式中 (.) 和 (.?) 匹配区别
(1) (.):贪婪匹配,尽可能多的匹配
(2) (.?):非贪婪匹配,尽可能少的匹配
举例如下:
贪婪匹配 (.*):
(.) 是贪婪匹配模式。这意味着它会尽可能多地匹配字符,直到无法匹配为止。在贪婪模式下,. 会匹配尽量多的字符。
text = "This is a test. This is another test."
pattern = re.compile(r'This is (.*) test\.')
match = pattern.search(text)
print(match.group(1))
输出结果
“a test. This is another”
非贪婪匹配(.*?)
(.?) 是非贪婪匹配模式。这表示它会尽可能少地匹配字符,直到满足条件为止。在非贪婪模式下,.? 会匹配尽量少的字符。
pattern = re.compile(r'This is (.*?) test\.')
match = pattern.search(text)
print(match.group(1))
输出结果:
“a”
Re 模块常用的三个匹配方法,并简述其特点
(1) Re.findall():以列表形式返回所有满足条件的对象
(2) Re.search():匹配到第一个就返回一个对象 ,用 group()取值,匹配不到返回 None
(3) Re.match():从字符串开头匹配,匹配返回一个对象,用 group()取值,匹配不到返回 None
Xpath 中根据索引定位节点数时,索引从 1 开始
示例
请列举爬虫中解析数据的模块
我使用的一般有以下四种库【模块】
lxml re bs4 json
我使用lxml内的etree与re来解析静态页面,常用用xpath定位数据节点,获取需要的数据。
Cookie 和 session 的区别
1. 数据存储位置不同:
Cookie 存储在客户端,通过浏览器的 Cookie 机制进行管理。Cookie 通常用于存储较小且不敏感的数据,例如用户偏好设置、跟踪信息等。
Session 存储在服务器端,客户端的 Cookie 中仅包含 Session ID。实际的用户数据存储在服务器上,这使得 Session 更安全。
2. 安全程度不同:
由于 Cookie 存储在客户端,可能被篡改或窃取,因此其安全性较低。可以通过加密或签名等方式提高安全性。
Session 存储在服务器上,只有 Session ID 存储在客户端,因此相对更安全。但仍需注意防止 Session Fixation 等攻击。
3. 性能不同:
Cookie 存储在客户端,不占用服务器资源,但每次请求都会携带 Cookie 数据,增加网络负担。
Session 存储在服务器,可能占用服务器内存,尤其在高访问量时,会增加服务器负载。
4. 数据存储大小不同:
单个 Cookie 通常不超过 4KB,且客户端浏览器对 Cookie 的数量有一定限制。
Session 存储在服务器,不受客户端浏览器限制,可以存储更大量级的数据。
结合使用的方式:在实际开发中,常常将 Session ID 存储在客户端的 Cookie 中,以维护用户的状态。
具体流程如下:
1. 用户通过用户名和密码登录。
2. 服务器创建一个 Session,并将用户的相关信息存储在 Session 中。
3. 服务器将 Session ID 发送给客户端浏览器,存储在 Cookie 中。
4. 客户端每次请求时,浏览器会自动携带 Cookie(包含 Session ID)。
5. 服务器通过解析 Cookie 中的 Session ID 获取用户信息。
这种方式既维护了用户状态,也避免了在 Cookie 中存储敏感信息。同时,可以通过一些安全措施,如使用 HttpOnly 标志、定期更换 Session ID 等,提高安全性。
json字符串与python字典数据相互转换
这里有一个json字符串,如果需要更新字符串里的内容,或者对数据进行持久化等操作,可以使用python将json转换为python字典进行操作。
使用 json.loads 将 JSON 字符串转换为 Python 字典。
python_dict = json.loads(json_str)
使用 json.dumps 将 Python 字典转换为 JSON 字符串
json_str = json.dumps(python_dict)
Selenium浏览器爬虫常用方法
-
driver.execute_script(js) 执行 JS 代码
-
定位元素的方法:
-
selenium获取当前页面源码
Html = browser.page_source -
添加代理
通过add_argument方法添加代理```proxy = "代理服务器的IP地址:端口号"chrome_options = webdriver.ChromeOptions()chrome_options.add_argument(f"--proxy-server={proxy}")# 创建Chrome浏览器驱动对象driver = webdriver.Chrome(chrome_options=chrome_options)```
添加代理的具体示例
-
添加cookie
driver.add_cookie(cookie)
添加cookie实现登录示例 -
使用无界面模式
options.add_grgument(“–headless”)options = webdriver.ChromeOptions() options.add_argument('--headless') driver = webdriver.Chrome(options=options)
什么是 i/o 密集型和计算密集型程序
I/O 密集型(I/O-bound)程序:
特点: 这种程序的特点是它们花费大部分时间等待输入/输出操作完成,而不是进行计算。在执行过程中,CPU 主要用于等待数据从存储器、磁盘、网络等 I/O 设备中读取或写入。
例子: 网络服务器、文件处理、数据库操作等。
计算密集型(CPU-bound)程序:
特点: 这种程序的特点是它们主要通过进行大量的数学计算或逻辑运算来消耗 CPU 时间。它们的执行主要依赖于 CPU 的处理能力,而不是等待外部设备的数据。
例子: 科学计算、图形渲染、密码学算法等。
对于 I/O 密集型任务,提高 I/O 操作的效率是关键。例如,使用异步编程、多线程或多进程来处理 I/O 操作,以便在等待数据时能够执行其他任务。对于计算密集型任务,通常需要更强大的 CPU 处理能力,可以考虑使用并行计算或分布式计算来加速任务的完成。