Python

基本数据类型

标准数据类型
Python3 中常见的数据类型有:

  • Number(数字)

  • String(字符串)

  • bool(布尔类型)

  • List(列表)

  • Tuple(元组)

  • Set(集合)

  • Dictionary(字典)

Python3 的六个标准数据类型中:

  • 不可变数据(3 个):Number(数字)、String(字符串)、Tuple(元组);

  • 可变数据(3 个):List(列表)、Dictionary(字典)、Set(集合)。

数据库

NoSQL数据库

NoSQL 数据库的特点

  1. 高扩展性:NoSQL 数据库通常设计为分布式系统,能够轻松扩展以处理大量数据和高并发请求。

  2. 灵活的数据模型:与传统关系型数据库不同,NoSQL 数据库不需要预定义的模式,可以存储各种格式的数据。

  3. 高性能:NoSQL 数据库在处理大数据量和高并发读写操作时表现出色。

  4. 最终一致性:NoSQL 数据库通常采用最终一致性模型,而不是严格的 ACID 特性(原子性、一致性、隔离性、持久性)。

最终一致性(Eventual Consistency)是分布式计算中的一种一致性模型。它指的是在分布式系统中,尽管数据在不同节点之间可能会有短暂的不一致,但经过一段时间后,所有节点上的数据最终会达到一致的状态。
关键特点

  1. 延迟一致性:数据更新后,不同节点上的数据可能不会立即同步,但最终会达到一致。

  2. 高可用性:通过允许短暂的不一致性,系统可以在高并发和网络分区的情况下保持高可用性。

  3. 乐观复制:通常通过乐观复制或延迟复制(lazy replication)实现,减少了同步的开销。

乐观复制(Optimistic Replication)是一种在分布式系统中使用的复制技术。它允许数据副本在短时间内出现不一致,但最终会达到一致状态。以下是乐观复制的主要特点和优点:
主要特点

  1. 允许并发操作:多个节点可以同时进行读写操作,而不需要立即同步。

  2. 后台同步:更新会在后台传播,减少了同步的开销。

  3. 冲突解决:在更新传播过程中,如果发生冲突,会在事后解决。
    优点

  4. 高可用性:即使网络连接不稳定,用户也可以访问本地副本。

  5. 扩展性:适用于大规模分布式系统,支持大量副本节点。

  6. 快速响应:用户可以立即看到自己的更改,提高用户体验。

NoSQL 数据库的分类

  1. 键值存储(Key-Value Stores):数据以键值对的形式存储,适用于简单的数据存储需求。例如:Redis, DynamoDB。

  2. 文档存储(Document Stores):数据以文档的形式存储,文档通常是 JSON 或 BSON 格式,适用于复杂的数据结构。例如:MongoDB, CouchDB。

  3. 列存储(Column Stores):数据以列的形式存储,适用于需要高效读写大数据量的场景。例如:Cassandra, HBase。

  4. 图数据库(Graph Databases):数据以图的形式存储,适用于处理复杂关系的数据。例如:Neo4j, ArangoDB。

适用场景

  • 社交网络:处理用户关系和动态数据。

  • 实时分析:处理和分析大规模实时数据。

  • 内容管理系统:存储和管理各种格式的内容。

  • 物联网(IoT):处理大量传感器数据。

抓包工具

工具

Wireshark:免费的网络协议分析工具,支持多个平台。
Fiddler:免费的HTTP和HTTPS调试工具,适用于Windows平台。
Charles:HTTP代理服务器和反向代理服务器,支持多个平台。
Burp Suite:面向Web应用程序测试的集成平台,支持多个平台。
Tcpdump:基于命令行界面的网络数据包分析工具,适用于多种Unix系统。

爬虫

如何绕过反爬机制

绕过反爬机制是一个复杂的问题,因为网站通常会使用多种方法来检测和阻止爬虫。以下是一些常见的反爬机制及其应对方法:

  1. 伪装请求头

    • 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'
    }
    
  2. 使用代理

    • 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)
    
  3. 处理Cookies

    • 保持会话: 使用会话对象来保持和服务器的会话状态,避免被识别为爬虫。

    session = requests.Session()
    response = session.get(url, headers=headers)
    
  4. 模拟浏览器行为

    • Selenium: 使用Selenium库来模拟真实的浏览器行为,包括处理JavaScript渲染的页面。

    from selenium import webdriver
    driver = webdriver.Chrome()
    driver.get(url)
    
  5. 处理验证码

    • 打码平台: 对于简单的图片验证码,可以使用OCR技术或打码平台来识别。

    from pytesseract import image_to_string
    from PIL import Image
    captcha_text = image_to_string(Image.open('captcha.png'))
    
  6. 动态加载数据

    • 抓包分析: 通过抓包工具(如Fiddler或Charles)分析数据请求,直接请求数据接口。

    import requests
    response = requests.get('https://example.com/api/data')
    data = response.json()
    

在Python爬虫的面试中,面试官可能会问一些关于爬虫技术、反爬虫策略、数据提取和存储等方面的问题。以下是一些常见的面试问题及其简要回答:

基础问题

  1. 什么是爬虫?它的作用是什么?

    • 爬虫是一种自动化程序,用于从网站上抓取信息。它的作用是收集和分析网络上的数据,用于各种应用场景,如数据分析、搜索引擎等。

  2. 解释爬虫的工作流程。

    • 爬虫的工作流程通常包括以下几个步骤:选择起始URL,下载网页内容,提取有用信息,跟踪链接,重复上述步骤。

  3. 列举几种常见的爬虫类型。

    • 通用爬虫:爬取整个互联网的数据。

    • 聚焦爬虫:针对特定领域或网站的数据。

    • 增量式爬虫:只爬取新增或更新的数据。

技术问题

  1. 你使用过哪些Python库或框架来进行爬虫开发?

    • 常见的库和框架包括:Requests、BeautifulSoup、Scrapy、Selenium、Pyppeteer等。

  2. 解释Scrapy框架的作用和优势。

    • Scrapy是一个开源的Python爬虫框架,用于构建和部署大规模的爬虫项目。它的优势包括高性能、易扩展性、强大的选择器和内置的异步处理机制。

  3. 如何在Scrapy中设置代理?

    • 可以通过在请求中设置proxy属性来使用代理,或者通过中间件来自动为每个请求设置代理。

数据提取与存储

  1. 解释正则表达式在爬虫中的应用。

    • 正则表达式用于从文本中提取特定模式的数据。在爬虫中,可以使用正则表达式从网页源代码中提取有用信息。

  2. 什么是XPath?它如何在爬虫中使用?

    • XPath是一种用于在XML和HTML文档中定位元素的语言。在爬虫中,可以使用XPath从网页中提取特定元素的数据。

  3. 如何将提取的数据存储到CSV文件中?

    • 可以使用Python的csv模块将提取的数据存储到CSV文件中。首先将数据转换为适合CSV格式的列表或字典,然后使用csv模块的writer对象将数据写入CSV文件。

反爬虫策略

  1. 列举几种常见的反爬虫策略。

    • User-Agent检测、验证码、IP封禁、动态加载、JavaScript数据加密、隐藏参数等。

  2. 如何应对User-Agent检测?

    • 可以通过设置User-Agent头部,使用常见的浏览器User-Agent,或者随机生成User-Agent来应对User-Agent检测。

  3. 如何处理验证码?

    • 处理验证码的方法包括使用验证码识别服务、人工输入验证码或使用第三方库自动识别验证码。

实战问题

  1. 如何处理JavaScript渲染的网页?

    • 可以使用Selenium或Pyppeteer等工具,这些工具可以模拟浏览器行为,执行JavaScript代码,并获取渲染后的网页内容。

  2. 如何应对动态加载的内容?

    • 可以分析AJAX请求,直接请求这些API获取数据,或者使用Selenium等工具模拟用户交互,触发动态内容的加载。

  3. 如何优化爬虫的性能?

    • 优化爬虫性能的方法包括使用异步请求、合理设置下载延迟、使用多线程或多进程、优化数据存储和提取过程、以及合理设计爬虫的结构和逻辑。

Scrapy架构

Scrapy 的特点

  1. 快速而强大: Scrapy 可以快速编写规则来提取数据,并自动处理请求、解析 HTML 网页、收集数据并保存为所需格式。

  2. 容易扩展: Scrapy 通过设计可扩展,无需接触核心即可轻松插入新功能。可以使用中间件来扩展 Scrapy 的功能。

  3. 跨平台: Scrapy 用 Python 编写,可以在 Linux、Windows、Mac 和 BSD 上运行。

Scrapy 的架构

Scrapy 的架构由多个组件组成,每个组件负责不同的任务。以下是 Scrapy 的主要组件:

  1. Engine(引擎): 控制系统所有组件之间的数据流,并在发生某些操作时触发事件。

  2. Scheduler(调度器): 接收来自引擎的请求,对其去重并放入请求队列中,然后按顺序返回给引擎。

  3. Downloader(下载器): 获取网页数据并将其返回给引擎,随后传给 Spiders(爬虫)。

  4. Spiders(爬虫): 解析响应,提取出 Items 和新的 Requests。

  5. Item Pipeline(项目管道): 处理爬虫提取的项目,进行清理、验证和持久化(如存储在数据库中)。

  6. Downloader Middlewares(下载器中间件): 处理从引擎传递到下载器的请求,以及从下载器传递到引擎的响应。

  7. Spider Middlewares(爬虫中间件): 处理爬虫的输入(响应)和输出(项目和请求)。

Scrapy 的工作流程

  1. 引擎: 从爬虫获取初始请求。

  2. 调度器: 对请求去重并排队,返回给引擎。

  3. 下载器: 下载网页并返回响应给引擎。

  4. 爬虫: 解析响应,提取数据和新的请求。

  5. 项目管道: 处理提取的数据。

  6. 重复上述过程,直到没有更多请求为止。

示例代码

以下是一个简单的 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 的一些关键特性和用法:
关键特性

  1. 事件驱动: Twisted 使用事件循环来处理网络事件,避免了传统的多线程模型。

  2. 多协议支持: 支持多种网络协议,包括 HTTP、SMTP、IMAP、SSH 等。

  3. 异步编程: 通过异步 I/O 操作,提高了网络应用的性能和响应速度。

  4. 可扩展性: 提供了丰富的扩展模块,可以轻松地添加新功能。

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 的问题可以涵盖多个方面,包括框架的基本概念、技术细节、实际应用和优化策略。以下是一些常见的面试问题及其简要回答:

基本概念

  1. 什么是 Scrapy?它的主要用途是什么?

    • Scrapy 是一个开源的、用于抓取网站数据并提取结构化数据的 Python 框架。它主要用于网络爬虫和数据挖掘。

  2. Scrapy 的基本架构是什么?

    • Scrapy 的基本架构包括引擎(Engine)、调度器(Scheduler)、下载器(Downloader)、爬虫(Spider)、项目管道(Item Pipeline)和中间件(Middleware)¹。

技术细节

  1. Scrapy 的调度器是如何工作的?

    • 调度器负责接收引擎发送的请求,将其去重并加入请求队列,然后按顺序返回给引擎进行处理。

  2. Scrapy 的去重机制是如何实现的?

    • Scrapy 使用请求指纹(Request Fingerprint)来去重。每个请求的 URL、请求方法、请求体等信息会生成一个唯一的哈希值,调度器通过检查这个哈希值来判断请求是否重复。

  3. Scrapy 中的中间件是什么?有什么作用?

    • 中间件是处理请求和响应的钩子。下载器中间件处理从引擎到下载器的请求和从下载器到引擎的响应;爬虫中间件处理从引擎到爬虫的响应和从爬虫到引擎的请求。

实际应用

  1. 如何在 Scrapy 中处理动态加载的内容?

    • 可以使用 Selenium 或 Pyppeteer 等工具来模拟浏览器行为,执行 JavaScript 代码,并获取渲染后的网页内容。

  2. 如何在 Scrapy 中使用代理?

    • 可以通过设置下载器中间件来使用代理。例如,使用 scrapy-proxies 插件或自定义下载器中间件来设置代理。

  3. 如何在 Scrapy 中处理验证码?

    • 可以使用打码平台或 OCR 技术来识别验证码,或者使用 Selenium 等工具手动处理验证码。

优化策略

  1. 如何优化 Scrapy 爬虫的性能?

    • 优化策略包括:使用异步请求、合理设置并发数和下载延迟、使用代理池、优化数据提取和存储过程。

  2. 如何在 Scrapy 中实现分布式爬虫?

    • 可以使用 scrapy-redis 来实现分布式爬虫。scrapy-redis 通过 Redis 数据库共享请求队列和去重集合,使多个爬虫实例可以协同工作。