# python-crawler **Repository Path**: MayLight/python-crawler ## Basic Information - **Project Name**: python-crawler - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-03-13 - **Last Updated**: 2025-03-13 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 模块化爬虫系统 这是一个基于Python的模块化爬虫系统,支持并发抓取网页内容,动态解析数据,并将结果保存为结构化JSON文件。 ## 系统特点 - **模块化设计**:分离输入、调度、下载、解析和存储功能 - **并发抓取**:支持多线程/协程并发下载,提高效率 - **动态解析**:通过配置文件定义不同网站的解析规则 - **插件化扩展**:支持自定义解析器插件 - **反爬策略**:内置User-Agent轮换、请求延迟等反爬措施 ## 目录结构 ``` crawler/ ├── config/ # 配置文件目录 │ ├── config.ini # 主配置文件 │ ├── rules.yaml # 解析规则配置 │ └── user_agents.txt # User-Agent列表 ├── crawler/ # 爬虫核心代码 │ ├── __init__.py │ ├── downloader.py # 下载器模块 │ ├── parser.py # 解析器模块 │ ├── scheduler.py # 调度器模块 │ └── storage.py # 存储模块 ├── parsers/ # 自定义解析器插件目录 │ ├── __init__.py │ └── example_parser.py # 示例解析器 ├── data/ # 数据存储目录 ├── logs/ # 日志目录 ├── main.py # 主程序入口 └── requirements.txt # 依赖包列表 ``` ## 安装与使用 ### 1. 安装依赖 ```bash pip install -r requirements.txt ``` ### 2. 配置解析规则 在 `config/rules.yaml` 中配置目标网站的解析规则,例如: ```yaml "example.com": title: "//h1/text()" content: "//div[@class='article']//text()" ``` ### 3. 运行爬虫 **单个URL**: ```bash python main.py --url "https://example.com/page1" ``` **批量URL**: ```bash python main.py --file urls.txt ``` **使用自定义配置**: ```bash python main.py --url "https://example.com" --config ./my_config.ini ``` ## 配置说明 ### 主配置文件 (config.ini) ```ini [DEFAULT] max_workers = 8 # 最大并发数 retry_times = 3 # 重试次数 save_path = ./data # 数据保存路径 user_agents = ./config/user_agents.txt # UA文件路径 proxy_enabled = False # 是否启用代理 request_delay = 2 # 请求间隔(秒) ``` ### 解析规则 (rules.yaml) 解析规则支持XPath和CSS选择器: ```yaml "example.com": title: "xpath://h1/text()" author: "css:span.author::text" content: "xpath://div[@class='content']//text()" ``` ## 高级功能 ### 链接提取与跟踪 系统支持从页面中提取链接并自动跟踪爬取: 1. **自动链接提取**:可以从当前页面提取所有链接,并根据配置规则决定是否跟踪 2. **链接过滤**:支持通过正则表达式或自定义函数过滤链接 3. **深度控制**:可以设置最大爬取深度,避免无限爬取 配置示例(config.ini): ```ini [LINK_EXTRACTOR] ; 是否启用链接提取 enabled = True ; 链接提取的选择器 selector = a[href] ; 链接过滤正则表达式,符合的链接会被跟踪爬取 follow_pattern = .*\.html$ ; 链接排除正则表达式,符合的链接会被排除 exclude_pattern = .*\.(jpg|jpeg|png|gif|css|js)$ ; 是否只提取同域名链接 same_domain_only = True ; 最大提取链接数 max_links = 100 ``` 也可以在规则文件(rules.yaml)中为特定网站配置链接提取规则: ```yaml "example.com": # 其他字段... # 简单链接提取规则 links_selector: "css:div.related a[href]" # 或者使用复杂规则 links_selector: css: "div.related-news a[href]" follow_pattern: ".*\/article\/.*\.html$" exclude_pattern: ".*\/(tag|category)\/.*" ``` ### 翻页支持 系统支持自动检测和处理分页内容: 1. **自动翻页**:可以配置翻页按钮的选择器,自动获取下一页URL 2. **最大页数限制**:可以设置最大爬取页数,避免无限爬取 3. **自定义翻页逻辑**:支持通过插件实现复杂的翻页逻辑 配置示例(config.ini): ```ini [PAGINATION] ; 是否启用翻页功能 enabled = True ; 下一页按钮的选择器(可以用逗号分隔多个选择器) next_page_selector = a.next-page, a:contains("下一页"), a[rel="next"] ; 最大页数限制 max_pages = 10 ; 翻页间隔时间(秒) page_delay = 3 ``` 也可以在规则文件(rules.yaml)中为特定网站配置翻页规则: ```yaml "example.com": # 其他字段... # 简单翻页规则 next_page_selector: "css:a.next-page" # 或者使用多个选择器(按顺序尝试) next_page_selector: - "css:a.next" - "xpath://a[contains(text(), '下一页')]" - "css:div.pagination a[rel='next']" ``` ### 实际使用示例 以下是一个完整的爬取电商网站产品列表的示例: 1. **配置规则文件**(rules.yaml): ```yaml "shop.example.com": product_name: "css:h1.product-title::text" product_price: xpath: "//span[@class='price']/text()" replace: "\\$": "" "\\s+": "" strip: true product_description: "css:div.product-description::text" # 提取所有商品链接 links_selector: "css:div.product-grid a.product-link" # 翻页规则 next_page_selector: "css:a.next-page" ``` 2. **运行爬虫**: ```bash python main.py --url "https://shop.example.com/products" --depth 3 ``` 这将: - 从产品列表页开始爬取 - 提取所有产品链接并跟踪爬取(最大深度为3) - 自动处理翻页,继续爬取下一页的产品 - 提取每个产品页面的名称、价格和描述 - 将结果保存为结构化JSON文件 ### 自定义链接提取器 如果配置不能满足需求,可以创建自定义链接提取器: ```python from crawler.link_extractor import BaseLinkExtractor from bs4 import BeautifulSoup import re class MyLinkExtractor(BaseLinkExtractor): def __init__(self): super().__init__() self.domains = ["mysite.com"] # 只处理这些域名 def extract_links(self, html, url): links = [] soup = BeautifulSoup(html, 'html.parser') # 示例:只提取商品详情页链接 for link in soup.select('a.product-link'): if 'href' in link.attrs: abs_url = urllib.parse.urljoin(url, link['href']) if self.should_follow(abs_url): links.append(abs_url) return links def should_follow(self, url): # 只跟踪商品详情页 return bool(re.search(r'/product/\d+', url)) ``` 将此文件保存为 `link_extractors/my_link_extractor.py`,系统会自动加载并使用它。 ### 自定义翻页处理器 同样,可以创建自定义翻页处理器处理复杂的翻页逻辑: ```python from crawler.paginator import BasePaginator from bs4 import BeautifulSoup import re import urllib.parse class MyPaginator(BasePaginator): def __init__(self): super().__init__() self.domains = ["mysite.com"] # 只处理这些域名 self.current_page = 1 self.max_pages = 10 def get_next_page(self, html, url): # 已达到最大页数 if self.current_page >= self.max_pages: return None soup = BeautifulSoup(html, 'html.parser') # 示例:处理AJAX分页 # 从当前URL提取页码参数 current_url = urllib.parse.urlparse(url) query_params = urllib.parse.parse_qs(current_url.query) # 获取当前页码,默认为1 page = int(query_params.get('page', ['1'])[0]) # 构建下一页URL next_page = page + 1 self.current_page = next_page # 替换或添加页码参数 query_params['page'] = [str(next_page)] new_query = urllib.parse.urlencode(query_params, doseq=True) # 构建新URL next_url_parts = list(current_url) next_url_parts[4] = new_query next_url = urllib.parse.urlunparse(next_url_parts) return next_url ``` 将此文件保存为 `paginators/my_paginator.py`,系统会自动加载并使用它。 ## 自定义解析器 如果配置不能满足需求,可以创建自定义解析器: 1. 在 `parsers/` 目录下创建新的Python文件 2. 继承 `BaseParser` 类并实现 `parse()` 方法 3. 系统会自动加载并根据域名匹配使用 ```python from crawler.parser import BaseParser class MyCustomParser(BaseParser): def __init__(self): # 指定支持的域名 self.domains = ["mysite.com"] def parse(self, html, url): # 自定义解析逻辑 result = { "title": "自定义提取的标题", "content": "自定义提取的内容" } return result ``` ## 输出结果 爬取的数据将保存在 `data/` 目录下,按域名和日期组织: ``` data/ ├── example.com/ │ └── 20250313.json └── another-site.org/ └── 20250313.json ``` 每个JSON文件包含爬取的结构化数据。 ## 注意事项 1. 请遵守网站的robots.txt规则 2. 避免高频率请求同一网站,合理设置请求延迟 3. 爬取内容仅用于个人学习和研究,请勿用于商业用途 ## 扩展计划 - [ ] 添加数据库存储支持 - [ ] 实现分布式爬取功能 - [ ] 添加Web界面管理爬虫任务