Python
基本数据类型
标准数据类型
Python3 中常见的数据类型有:
Number(数字)
String(字符串)
bool(布尔类型)
List(列表)
Tuple(元组)
Set(集合)
Dictionary(字典)
Python3 的六个标准数据类型中:
不可变数据(3 个):Number(数字)、String(字符串)、Tuple(元组);
可变数据(3 个):List(列表)、Dictionary(字典)、Set(集合)。
数据库
NoSQL数据库
NoSQL 数据库的特点
高扩展性:NoSQL 数据库通常设计为分布式系统,能够轻松扩展以处理大量数据和高并发请求。
灵活的数据模型:与传统关系型数据库不同,NoSQL 数据库不需要预定义的模式,可以存储各种格式的数据。
高性能:NoSQL 数据库在处理大数据量和高并发读写操作时表现出色。
最终一致性:NoSQL 数据库通常采用最终一致性模型,而不是严格的 ACID 特性(原子性、一致性、隔离性、持久性)。
最终一致性(Eventual Consistency)是分布式计算中的一种一致性模型。它指的是在分布式系统中,尽管数据在不同节点之间可能会有短暂的不一致,但经过一段时间后,所有节点上的数据最终会达到一致的状态。
关键特点
延迟一致性:数据更新后,不同节点上的数据可能不会立即同步,但最终会达到一致。
高可用性:通过允许短暂的不一致性,系统可以在高并发和网络分区的情况下保持高可用性。
乐观复制:通常通过乐观复制或延迟复制(lazy replication)实现,减少了同步的开销。
乐观复制(Optimistic Replication)是一种在分布式系统中使用的复制技术。它允许数据副本在短时间内出现不一致,但最终会达到一致状态。以下是乐观复制的主要特点和优点:
主要特点
允许并发操作:多个节点可以同时进行读写操作,而不需要立即同步。
后台同步:更新会在后台传播,减少了同步的开销。
冲突解决:在更新传播过程中,如果发生冲突,会在事后解决。
优点高可用性:即使网络连接不稳定,用户也可以访问本地副本。
扩展性:适用于大规模分布式系统,支持大量副本节点。
快速响应:用户可以立即看到自己的更改,提高用户体验。
NoSQL 数据库的分类
键值存储(Key-Value Stores):数据以键值对的形式存储,适用于简单的数据存储需求。例如:Redis, DynamoDB。
文档存储(Document Stores):数据以文档的形式存储,文档通常是 JSON 或 BSON 格式,适用于复杂的数据结构。例如:MongoDB, CouchDB。
列存储(Column Stores):数据以列的形式存储,适用于需要高效读写大数据量的场景。例如:Cassandra, HBase。
图数据库(Graph Databases):数据以图的形式存储,适用于处理复杂关系的数据。例如:Neo4j, ArangoDB。
适用场景
社交网络:处理用户关系和动态数据。
实时分析:处理和分析大规模实时数据。
内容管理系统:存储和管理各种格式的内容。
物联网(IoT):处理大量传感器数据。
抓包工具
工具
Wireshark:免费的网络协议分析工具,支持多个平台。
Fiddler:免费的HTTP和HTTPS调试工具,适用于Windows平台。
Charles:HTTP代理服务器和反向代理服务器,支持多个平台。
Burp Suite:面向Web应用程序测试的集成平台,支持多个平台。
Tcpdump:基于命令行界面的网络数据包分析工具,适用于多种Unix系统。
爬虫
如何绕过反爬机制
绕过反爬机制是一个复杂的问题,因为网站通常会使用多种方法来检测和阻止爬虫。以下是一些常见的反爬机制及其应对方法:
伪装请求头
User-Agent: 许多网站会检查请求的User-Agent字段,以判断请求是否来自浏览器。你可以通过设置一个常见的浏览器User-Agent来伪装爬虫¹。
headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3' }
使用代理
IP代理池: 使用代理服务器可以隐藏你的真实IP地址,从而避免因频繁请求而被封禁。
proxies = { 'http': 'http://10.10.1.10:3128', 'https': 'http://10.10.1.10:1080', } response = requests.get(url, headers=headers, proxies=proxies)
处理Cookies
保持会话: 使用会话对象来保持和服务器的会话状态,避免被识别为爬虫。
session = requests.Session() response = session.get(url, headers=headers)
模拟浏览器行为
Selenium: 使用Selenium库来模拟真实的浏览器行为,包括处理JavaScript渲染的页面。
from selenium import webdriver driver = webdriver.Chrome() driver.get(url)
处理验证码
打码平台: 对于简单的图片验证码,可以使用OCR技术或打码平台来识别。
from pytesseract import image_to_string from PIL import Image captcha_text = image_to_string(Image.open('captcha.png'))
动态加载数据
抓包分析: 通过抓包工具(如Fiddler或Charles)分析数据请求,直接请求数据接口。
import requests response = requests.get('https://example.com/api/data') data = response.json()
在Python爬虫的面试中,面试官可能会问一些关于爬虫技术、反爬虫策略、数据提取和存储等方面的问题。以下是一些常见的面试问题及其简要回答:
基础问题
什么是爬虫?它的作用是什么?
爬虫是一种自动化程序,用于从网站上抓取信息。它的作用是收集和分析网络上的数据,用于各种应用场景,如数据分析、搜索引擎等。
解释爬虫的工作流程。
爬虫的工作流程通常包括以下几个步骤:选择起始URL,下载网页内容,提取有用信息,跟踪链接,重复上述步骤。
列举几种常见的爬虫类型。
通用爬虫:爬取整个互联网的数据。
聚焦爬虫:针对特定领域或网站的数据。
增量式爬虫:只爬取新增或更新的数据。
技术问题
你使用过哪些Python库或框架来进行爬虫开发?
常见的库和框架包括:Requests、BeautifulSoup、Scrapy、Selenium、Pyppeteer等。
解释Scrapy框架的作用和优势。
Scrapy是一个开源的Python爬虫框架,用于构建和部署大规模的爬虫项目。它的优势包括高性能、易扩展性、强大的选择器和内置的异步处理机制。
如何在Scrapy中设置代理?
可以通过在请求中设置
proxy
属性来使用代理,或者通过中间件来自动为每个请求设置代理。
数据提取与存储
解释正则表达式在爬虫中的应用。
正则表达式用于从文本中提取特定模式的数据。在爬虫中,可以使用正则表达式从网页源代码中提取有用信息。
什么是XPath?它如何在爬虫中使用?
XPath是一种用于在XML和HTML文档中定位元素的语言。在爬虫中,可以使用XPath从网页中提取特定元素的数据。
如何将提取的数据存储到CSV文件中?
可以使用Python的
csv
模块将提取的数据存储到CSV文件中。首先将数据转换为适合CSV格式的列表或字典,然后使用csv
模块的writer
对象将数据写入CSV文件。
反爬虫策略
列举几种常见的反爬虫策略。
User-Agent检测、验证码、IP封禁、动态加载、JavaScript数据加密、隐藏参数等。
如何应对User-Agent检测?
可以通过设置User-Agent头部,使用常见的浏览器User-Agent,或者随机生成User-Agent来应对User-Agent检测。
如何处理验证码?
处理验证码的方法包括使用验证码识别服务、人工输入验证码或使用第三方库自动识别验证码。
实战问题
如何处理JavaScript渲染的网页?
可以使用Selenium或Pyppeteer等工具,这些工具可以模拟浏览器行为,执行JavaScript代码,并获取渲染后的网页内容。
如何应对动态加载的内容?
可以分析AJAX请求,直接请求这些API获取数据,或者使用Selenium等工具模拟用户交互,触发动态内容的加载。
如何优化爬虫的性能?
优化爬虫性能的方法包括使用异步请求、合理设置下载延迟、使用多线程或多进程、优化数据存储和提取过程、以及合理设计爬虫的结构和逻辑。
Scrapy架构
Scrapy 的特点
快速而强大: Scrapy 可以快速编写规则来提取数据,并自动处理请求、解析 HTML 网页、收集数据并保存为所需格式。
容易扩展: Scrapy 通过设计可扩展,无需接触核心即可轻松插入新功能。可以使用中间件来扩展 Scrapy 的功能。
跨平台: Scrapy 用 Python 编写,可以在 Linux、Windows、Mac 和 BSD 上运行。
Scrapy 的架构
Scrapy 的架构由多个组件组成,每个组件负责不同的任务。以下是 Scrapy 的主要组件:
Engine(引擎): 控制系统所有组件之间的数据流,并在发生某些操作时触发事件。
Scheduler(调度器): 接收来自引擎的请求,对其去重并放入请求队列中,然后按顺序返回给引擎。
Downloader(下载器): 获取网页数据并将其返回给引擎,随后传给 Spiders(爬虫)。
Spiders(爬虫): 解析响应,提取出 Items 和新的 Requests。
Item Pipeline(项目管道): 处理爬虫提取的项目,进行清理、验证和持久化(如存储在数据库中)。
Downloader Middlewares(下载器中间件): 处理从引擎传递到下载器的请求,以及从下载器传递到引擎的响应。
Spider Middlewares(爬虫中间件): 处理爬虫的输入(响应)和输出(项目和请求)。
Scrapy 的工作流程
引擎: 从爬虫获取初始请求。
调度器: 对请求去重并排队,返回给引擎。
下载器: 下载网页并返回响应给引擎。
爬虫: 解析响应,提取数据和新的请求。
项目管道: 处理提取的数据。
重复上述过程,直到没有更多请求为止。
示例代码
以下是一个简单的 Scrapy 爬虫示例,展示了如何抓取一个网站的数据:
import scrapy
class ExampleSpider(scrapy.Spider):
name = 'example'
start_urls = ['http://example.com']
def parse(self, response):
self.log(f'Visited {response.url}')
# 处理响应数据
Scrapy如何实现的多线程
Scrapy 实现多线程爬虫主要依赖于 Twisted 框架的异步特性。Twisted 是一个事件驱动的网络引擎,能够高效地处理并发请求。以下是 Scrapy 实现多线程爬虫的关键点:
1. 异步请求处理
Scrapy 使用 Twisted 来处理网络请求,这意味着它可以在等待响应时继续处理其他任务,而不是阻塞等待。这种异步处理方式使得 Scrapy 能够高效地进行并发爬取。
Twisted 是一个用 Python 编写的事件驱动网络引擎,适用于构建各种网络应用。它支持异步 I/O 操作,使得处理并发任务更加高效。以下是 Twisted 的一些关键特性和用法:
关键特性
事件驱动: Twisted 使用事件循环来处理网络事件,避免了传统的多线程模型。
多协议支持: 支持多种网络协议,包括 HTTP、SMTP、IMAP、SSH 等。
异步编程: 通过异步 I/O 操作,提高了网络应用的性能和响应速度。
可扩展性: 提供了丰富的扩展模块,可以轻松地添加新功能。
2. 配置并发参数
通过配置 Scrapy 的设置文件,可以控制并发请求的数量和频率。例如:
CONCURRENT_REQUESTS
: 设置 Scrapy 同时处理的最大请求数。CONCURRENT_REQUESTS_PER_DOMAIN
: 设置每个域名同时处理的最大请求数。CONCURRENT_REQUESTS_PER_IP
: 设置每个 IP 同时处理的最大请求数。DOWNLOAD_DELAY
: 设置下载延迟,防止过于频繁的请求导致被封禁。
# settings.py
CONCURRENT_REQUESTS = 100
CONCURRENT_REQUESTS_PER_DOMAIN = 16
CONCURRENT_REQUESTS_PER_IP = 16
DOWNLOAD_DELAY = 0.25 # 250 ms of delay
3. 使用 Twisted 的异步特性
Scrapy 内部使用 Twisted 的异步 I/O 来处理请求和响应,这使得它能够在单线程中实现高效的并发处理。每个请求都是一个异步操作,当一个请求在等待响应时,Scrapy 可以处理其他请求。
4. 中间件和扩展
Scrapy 提供了多种中间件和扩展,可以进一步优化并发爬取的性能。例如,使用下载中间件来处理代理、重试和限速等。
在面试中,关于 Scrapy 的问题可以涵盖多个方面,包括框架的基本概念、技术细节、实际应用和优化策略。以下是一些常见的面试问题及其简要回答:
基本概念
什么是 Scrapy?它的主要用途是什么?
Scrapy 是一个开源的、用于抓取网站数据并提取结构化数据的 Python 框架。它主要用于网络爬虫和数据挖掘。
Scrapy 的基本架构是什么?
Scrapy 的基本架构包括引擎(Engine)、调度器(Scheduler)、下载器(Downloader)、爬虫(Spider)、项目管道(Item Pipeline)和中间件(Middleware)¹。
技术细节
Scrapy 的调度器是如何工作的?
调度器负责接收引擎发送的请求,将其去重并加入请求队列,然后按顺序返回给引擎进行处理。
Scrapy 的去重机制是如何实现的?
Scrapy 使用请求指纹(Request Fingerprint)来去重。每个请求的 URL、请求方法、请求体等信息会生成一个唯一的哈希值,调度器通过检查这个哈希值来判断请求是否重复。
Scrapy 中的中间件是什么?有什么作用?
中间件是处理请求和响应的钩子。下载器中间件处理从引擎到下载器的请求和从下载器到引擎的响应;爬虫中间件处理从引擎到爬虫的响应和从爬虫到引擎的请求。
实际应用
如何在 Scrapy 中处理动态加载的内容?
可以使用 Selenium 或 Pyppeteer 等工具来模拟浏览器行为,执行 JavaScript 代码,并获取渲染后的网页内容。
如何在 Scrapy 中使用代理?
可以通过设置下载器中间件来使用代理。例如,使用
scrapy-proxies
插件或自定义下载器中间件来设置代理。
如何在 Scrapy 中处理验证码?
可以使用打码平台或 OCR 技术来识别验证码,或者使用 Selenium 等工具手动处理验证码。
优化策略
如何优化 Scrapy 爬虫的性能?
优化策略包括:使用异步请求、合理设置并发数和下载延迟、使用代理池、优化数据提取和存储过程。
如何在 Scrapy 中实现分布式爬虫?
可以使用
scrapy-redis
来实现分布式爬虫。scrapy-redis
通过 Redis 数据库共享请求队列和去重集合,使多个爬虫实例可以协同工作。