LeetCode Archiver(1):Scrapy框架和Requests库

简介 Scrapy官方文档对Scrapy的介绍如下: Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架。可以应用在包括数据挖掘,信息处理或存储历史数据等一系列的程序中。其最初是为了页面抓取(更确切来说, 网络抓取)所设计的,也可以应用在获取API所返回的数据(例如 Amazon Associates Web Services )或者通用的网络爬虫。 简而言之,Scrapy是基于Twisted库开发的,封装了http请求、代理信息、数据存储等功能的Python爬虫框架。 组件和数据流 下图是Scrapy官方文档中的架构概览图: 图中绿色箭头表示数据流,其他均为组件。 Scrapy Engine(引擎) 引擎负责控制数据流在系统的组件中流动,并在相应动作发生时触发事件。 Scheduler(调度器) 调度器从引擎接收request并将其保存,以便在引擎请求时提供给引擎。 Downloader(下载器) 下载器负责下载页面数据,并将其提供给引擎,而后再由引擎提供给爬虫。 Spiders(爬虫) Spider是由用户编写的用于分析response并提取item或额外跟进url的类。一个Scrapy项目中可以有很多Spider,他们分别被用于爬取不同的页面和网站。 Item Pipeline(管道) Item Pipeline负责处理被爬虫提取出来的item。可以对其进行数据清洗,验证和持久化(例如存储到数据库中)。 Downloader middlewares(下载器中间件) 下载器中间件是在引擎及下载器之间的组件,用于处理下载器传递给引擎的response。更多内容请参考下载器中间件。 Spider middlewares(爬虫中间件) Spider中间件是在引擎及Spider之间的组件,用于处理爬虫的输入(response)和输出(items和requests)。更多内容请参考爬虫中间件。 Data flow(数据流) Scrapy中的数据流由引擎控制,其过程如下: 1.引擎打开一个网站,找到处理该网站的爬虫并向该爬虫请求要爬取的url。 2.引擎从爬虫中获取到要爬取的url并将其作为request发送给调度器。 3.引擎向调度器请求下一个要爬取的url。 4.调度器返回下一个要爬取的url给引擎,引擎将url通过下载器中间件发送给下载器。 5.下载器下载页面成功后,生成一个该页面的response对象,并将其通过下载器中间件发送给引擎。 6.引擎接收从下载器中间件发送过来的response,并将其通过爬虫中间件发送给爬虫处理。 7.爬虫处理response,并将爬取到的item及跟进的新的request发送给引擎。 8.引擎将爬虫返回的item发送给管道,将爬虫返回的新的request发送给调度器。 9.管道对item进行相应的处理。 10.重复第二步,直到调度器中没有更多的request,此时引擎关闭该网站。 安装 1.下载安装最新版的Python3 2.使用pip指令安装Scrapy pip3 install scrapy 创建项目 首先进入你的代码存储目录,在命令行中输入以下命令: scrapy startproject LeetCode_Crawler 注意项目名称是不能包含连字符 ‘-’ 的 新建成功后,可以看到在当前目录下新建了一个名为LeetCode_Crawler的Scrapy项目,进入该目录,其项目结构如下: scrapy.cfg #该项目的配置文件 scrapy_project #该项目的Python模块 __init__.py items.py #可自定义的item类文件 middlewares.py #中间件文件 pipelines.py #管道文件 settings....

December 4, 2018 · 1 min

C++ 基础知识整理

C++ 基础知识 const 相关 #define,typedef,const # 是宏,宏不做类型检查,只进行简单替换;在编译前被处理,编译阶段的程序是宏处理后的结果 typedef 用于声明自定义数据类型,简化代码 const 用于定义常量,有数据类型,编译器会对进行类型检查 const 和指针 const char *p: p is a pointer to const char char const *p: p is a pointer to char const(同上) char *const p: p is a const pointer to char int main() { const char *p1 = new char('a'); char const *p2 = new char('b'); char *const p3 = new char('c'); *p1 = 'd'; // error: read-only variable is notassignable *p2 = 'e'; // error: read-only variable is notassignable p3 = new char('f'); // error: cannot assign tovariable 'p3' with const-qualified type 'char *const' p3 = nullptr; // error: cannot assign to variable'p3' with const-qualified type 'char *const' } const 和类...

July 5, 2015 · 5 min

查看 container 的 log file 所在的目录:docker inspect <containername> | grep log

1 min

Linux: 我平时的学习基本上都在Linux下完成的,我现在有两台电脑,一台iMac,一台笔记本,笔记本上就装的Linux,然后每天都会用很多指令, 比如说用pipeline管道输出后用grep做正则搜索,用ifconfig和netstat查看网络状态,用top看进程资源,用iostat看cpu和硬盘状态 还有就是最基础的cd ls cp rm mkdir find whereis,还有远程的scp 还有一个查看程序运行时的系统调用,在Linux下是strace,Mac下是dtruss,有些命令在两个平台不一样 Linux下对文件操作有两种方式:系统调用(底层调用,面向硬件),和库函数调用(应用)。系统调用:open, close, read, write, ioctl等,用于底层文件访问 调试: 用vim编辑(会一些vim的快捷键,比如dd删除一行,gg定位到头部,6$定位到某一行),用gdb调试,打log出来看,用过有个叫log4cplus的框架,有内存错误或者内存泄漏的问题就用valgrind调试。还有用GNU profiler来查看一些函数的调用次数,调用点相关的信息(编译器的话在Linux上GCC,在MAC上用自带的clang,单元测试用gtest。) C++ 内存分配 栈区:参数,局部变量 2.堆区:new,向高地址扩展,不连续 3.自由存储区,malloc 4.全局/静态存储区,存储全局变量和静态变量 5.常量存储区,存储常量 new 分配失败: 1. int* p = new (std::nothrow) int(1); 返回空指针 2. 用 try {} catch (const bad_alloc &b) {} 捕捉异常 auto_ptr:有拷贝构造和赋值操作,所有权转移 unique_ptr:独占式拥有,保证同一时间内只有一个智能指针可以指向特定指针,同时销毁,可以移交拥有权 shared_ptr:多个智能指针指向相同指针对象,在最后一个shared_ptr被销毁时对象被释放;搭配 weak_ptr、bad_weak_ptr等辅助类来实现,可以定制型删除器,因为默认只会把指针删掉,如果是个数组不会删后面的 循环引用就是说有两个类对象的智能指针,他们分别有一个成员变量是对方的类型,并且指向了对方的智能指针,形成了一个环状,那么他们就无法被正确的释放掉 weak_ptr:只引用,不计数,如果一个指针被一些shared_ptr和weak_ptr同时引用,当这些shared_ptr都释放掉,不管还有没有weak_ptr引用该内存,内存都会被释放,解决了循环引用 线程通信:锁(互斥锁,读写所,自旋锁,条件变量,原子变量,临界区),信号量,信号,屏障

1 min