# spider **Repository Path**: dexterslab/spider ## Basic Information - **Project Name**: spider - **Description**: 爬虫项目 - **Primary Language**: Python - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2021-12-24 - **Last Updated**: 2022-04-11 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 说明文档 V0.0.1 ### 环境 * python >= 3.6 * pip (python默认自带) ### 安装 ```shell cd spider pip install -r requirements.txt ``` ### 使用 ```shell cd spider ######### 任务1 ######### # 运行支持elcano结构的页面 scrapy crawl elcano # 运行支持elcano-blog结构的页面 scrapy crawl elcano-blog # 运行支持elcano-brussels结构的页面 scrapy crawl elcano-brussels # 运行支持elcano-event结构的页面 scrapy crawl elcano-event # 运行支持elcano-notas结构的页面 scrapy crawl elcano-notas # 运行支持elcano-reports结构的页面 scrapy crawl elcano-reports ######### 任务2 ######### scrapy crawl iss ######### 任务3 ######### scrapy crawl ceps scrapy crawl cfr # scrapy crawl econpol scrapy crawl greengrowthknowledge ######### 任务4 ######### # 无法访问 ######### 任务5 ######### scrapy crawl epc scrapy crawl publication ######### 任务6 ######### scrapy crawl schuman ######### 任务7 ######### scrapy crawl kas ######### 任务8 ######### scrapy crawl ecdpm scrapy crawl ecdpm2 ######### 任务9 ######### scrapy crawl giga scrapy crawl giga2 ######### 任务10 ######### scrapy crawl dgap ``` ### 个性化配置 * settings.py文件 ```env # 注释掉LOG_*变量则为关闭日志文件输出,日志会在控制台输出 # 日志相关配置,注释掉之后不记录日志 # LOG_LEVEL = 'DEBUG' # LOG_FILE = 'log/scrapy_{}.log'.format(TODAY_STR) # 是否遵循爬虫的robots.txt协议 ROBOTSTXT_OBEY = False # 导出文件目录和文件名 DOWNLOAD_FILE_NAME = 'download/{}_{}_{}_{}.csv'.format('{}', today.year, today.month, today.day) # 是否为增量爬取数据,增量爬取只下载今天更新的内容 DOWNLOAD_TODAY = False # 是否过滤重复数据,对于不同页面的相同文章,是否只记录一条数据 DEDUPLICATED = True # 导入数据库配置 DB_HOST = '127.0.0.1' DB_PORT = 3306 DB_USER = 'root' DB_PASSWORD = 'ABC123' DB_DATABASE = 'UIBE_DC' # 调度器配置 # 调度 SCHEDULER = "scrapy_redis.scheduler.Scheduler" # 默认使用优先级队列 SCHEDULER_QUEUE_CLASS = 'scrapy_redis.queue.LifoQueue' # 调度器中请求存据进行序列化,默认使用pickle SCHEDULER_QUEUE_KEY = '%(spider)s:requests' # 是否在关闭时候保留原来的调度器和去重记录 SCHEDULER_PERSIST = True # 是否在开始之前清空调度器和去重记录 SCHEDULER_FLUSH_ON_START = False # 去调度器中获取数据时,如果为空,最多等待时间 SCHEDULER_IDLE_BEFORE_CLOSE = 10 # 去重规则,在redis中保存时对应的key SCHEDULER_DUPEFILTER_KEY = '%(spider)s:dupefilter' #去重的配置 # 去重规则对应处理的类 DUPEFILTER_CLASS = 'scrapy_redis.dupefilter.RFPDupeFilter' # 去重Debug模式 DUPEFILTER_DEBUG = False # 是否开启redis,如果不开启,爬虫继承scrapy.Spider,否则继承RedisSpider REDIS_ON = False EXTENDS_SPIDER = RedisSpider if REDIS_ON else scrapy.Spider # redis master配置 REDIS_HOST = '127.0.0.1' REDIS_PORT = 6379 # 下载PDF目录配置 FILES_STORE = '/tmp/{}/'.format(TODAY_STR) ``` ### 代码结构 * ___spider/log/___ : 默认日志目录 * ___spider/spider/spiders/elcano.py___ : 符合elcano结构的页面爬虫逻辑文件 * ___spider/spider/spiders/elcanoBlog.py___ : 符合elcanoBlog结构的页面爬虫逻辑文件 * ___spider/spider/spiders/elcanoBrussels.py___ : 符合elcanoBrussels结构的页面爬虫逻辑文件 * ___spider/spider/spiders/elcanoEvent.py___ : 符合elcanoEvent结构的页面爬虫逻辑文件 * ___spider/spider/spiders/elcanoNotas.py___ : 符合elcanoNotas结构的页面爬虫逻辑文件 * ___spider/spider/spiders/elcanoReports.py___ : 符合elcanoReports结构的页面爬虫逻辑文件 * ___spider/spider/items/items.py___ : 数据结构 * ___spider/spider/middlewares/middlewares.py___ : 中间件 * ___spider/spider/pipelines/mysqlPipeline.py___ : mysql管道文件,用于持久化数据 * ___spider/spider/pipelines/filesPipeline.py___ : 文件管道文件,用于下载PDF附件 * ___spider/database/mysql.py___ : Mysql数据库连接池 * ___spider/spider/mysqlUtil.py___ : Mysql通用方法封装 * ___spider/spider/settings.py___ : 全局配置 * ___spider/spider/utils.py___ : 通用方法 ### 注意事项 * ___约定的规范:带url的字段加了超链接标识,可以直接点击___ * ___同一天的下载文件名相同,所以重复执行会覆盖已有的文件___ * ___已经打开的文件,写入会报无法写入错误___ * ___定时调度本版本需要借助系统自带的调度工具,如crontab等___ ### 遇到的问题 1. 任务存在**多页面结构差异巨大**的问题,无法复用同一个爬虫逻辑,本次经反复测试,一共写了**6个爬虫逻辑**处理全部页面; 2. 任务页面有一些页面,**包含的信息不完全**,而导入数据库的非空字段需要包含缺失的信息,导致无法导入; ```markdown 1. /wps/portal/rielcano_en/publications/boletin-newsletter-eng ** (没有正文) ** 2. /wps/portal/rielcano_en/publications/inside-spain ** (没有正文) ** 3. /wps/portal/rielcano_es/publicaciones/novedades ** (西语日期,可以做) ** 4. /wps/portal/rielcano_en/events/forthcoming-events ** (没有正文) ** ``` 3. **某些字段格式不规则**,难于处理,以副标题提取日期和作者为例,存在非常多的case,都需要兼容适配 ```markdown 1. 'Eric L. Olson & Nina Gordon. ARI 79/2018 - 25/6/2018.' 2. 'Antonio L. Mazzitelli. ARI 43/2006 - 6.4.2006.' 3. 'Alice Billon-Galland. 30/12/2021.' 4. 'Sanoussi Bilal. WP 12/2021 - 17/12/2021.' 5. 'Félix Arteaga, Raquel García, Ignacio Molina, Andrés Ortega, Miguel Otero, Charles Powell & Federico Steinberg. 02/11/2021.' 6. 'William Chislett. \
15/10/2012\
.' 7. 'Haizam Amirah-Fernández. Expert Comment 25/2015 (English versión) - 30/30/2015' 8. 'Real Instituto Elcano. (English version). December 2015' ** 上面的例子存在着日期格式不统一、日期数据错误(没有30/30/2015)、日期英文混用、标签混合、缺省来源等一系列问题 ** ``` 4. **结果验证耗时**,由于页面异构和页面数量多的因素,对结果的验证是一个非常耗时的工作,个人对本次任务做了4种验证检查方式 ```markdown 1. 比较数据条数与预期结果是否一致; 2. 抽查比较每种爬虫的结果字段是否符合预期; 3. 附件文件下载是否正常,文件名是否正确; 4. 对所有日志里异常进行跟踪定位,并分析原因; ** 结果验证是个非常费时费力的工作,以比较数据条数为例,期间遇到的问题、原因和解决办法如下: ** 1. ** 插入数据条数跟预期结果不一致,日志没有报错: ** 经过排除法测试,数据库page_url、page_text_body、 page_file_link、page_file_save_path、page_author 字段设置过小导致,修改大小,数据可以导入; 2. ** 插入数据条数跟预期结果不一致,日志没有报错: ** 页面结构异构,无法写兼容逻辑或者维护兼容逻辑太复杂,需要不同逻辑处理, 新增爬虫,处理异构页面,数据正常; 3. ** 插入数据条数跟预期结果不一致,日志没有报错: ** 少量页面的少量数据,是前端脚本动态插入,爬虫爬取时,拿不到数据,且该数据为非空字段, 所以无法导入。没有太好的办法,治本的解决方案是通过前端运行环境,拿到最终页面,代价大, 目前通过硬编码解决; 4. ** 插入数据条数跟预期结果不一致,日志没有报错: ** 抽取数据时没有拿到对应DOM节点,原因是 scrapy的某些复杂选择器, 比如nth-child(),兄弟选择器不起作用,需要用其他手段处理 5. ** 加入scrapy-redis后报错 ** scrapy-redis依赖包tabulate跟python 3.10冲突,需要降级到3.9 等等... ```