0. 基本环境说明
-
本文截图及运行环境均在MAC OS X 10.9.5上实现,但基本步骤与win 7环境上相同(其实我是先在win7折腾了一把,然后为了写这篇教程,又在OS X 上面重新搞了一遍)
-
scrapy版本为1.0
-
参考文献以及下载链接:
1. 基本环境配置
1. anaconda
刚接触python和机器学习的人,想必已经被python中眼花缭乱的安装包和相关类库搞的菊花一紧。我之前也是各种血泪史,完全没有老司机带着我。折腾了差不多半个月,python环境依旧装的破破烂烂。Windows和linux以及MACOS环境下都是演过了,各种蛋疼。直到某一天我见到了anaconda。才感觉这个世界上依旧是好人多,人间还是充满爱的。
anaconda是一个开源的、免费的python类库的集合,貌似一装就安装了200+的包,各种依赖包各种搞定。所以赶快戳顶层链接去下载吧。下面介绍的其他工具一些是anaconda自带的,一些是通过anaconda安装的,总之,anaconda是一切的基石。
2. MySQL 模块安装
anaconda模块竟然木有自带MySQL连接模块,用下面的命令来安装吧,后面抓取的内容要塞到数据库里面的哟~
conda install MySQL-python
3. scrapy 安装
下面就是安装scrapy了,其实也是简单的不要要的~,因为我们已经安装了anaconda,所以一切都简单的不要要的哟~,里面会让你有些包更新,直接输入y确认就好了。
conda install scrapy
注意:在使用conda install 安装的过程中,有时候因为网络问题或者其他问题会引起失败,此时要仔细看提示说明,寻找原因,如果是网络原因的话,重新输入以上命令即可~。我教研室有个师弟,因为网络原因装了8回,所以骚年洗洗菊花做好准备吧~
scrapy入门教程2:建立一个简单的爬取南邮新闻标题的爬虫demo
0. 基本环境说明
-
本文截图及运行环境均在MAC OS X 10.9.5上实现,但基本步骤与win 7环境上相同(其实我是先在win7折腾了一把,然后为了写这篇教程,又在OS X 上面重新搞了一遍)
-
scrapy版本为1.0
-
参考文献以及下载链接:
1. 建立步骤
通过上一篇内容我们已经将scrapy环境配置完毕,下面我们来实现一个demo来爬取南京邮电大学新闻页面的内容。
1. 创建一个新工程
scrapy startproject njupt #其中njupt是项目名称,可以按照个人喜好来定义
输入以上命令之后,就会看见命令行运行的目录下多了一个名为njupt的目录,目录的结构如下:
|---- njupt | |---- njupt | |---- __init__.py | |---- items.py #用来存储爬下来的数据结构(字典形式) | |---- pipelines.py #用来对爬出来的item进行后续处理,如存入数据库等 | |---- settings.py #爬虫配置文件 | |---- spiders #此目录用来存放创建的新爬虫文件(爬虫主体) | |---- __init__.py | |---- scrapy.cfg #项目配置文件
至此,工程创建完毕。
2. 设置 items
本文以抓取南邮新闻为例,需要存储三种信息:
-
南邮新闻标题
-
南邮新闻时间
-
南邮新闻的详细链接
items内部代码如下:
# -*- coding: utf-8 -*- import scrapy class NjuptItem(scrapy.Item): #NjuptItem 为自动生成的类名 news_title = scrapy.Field() #南邮新闻标题 news_date = scrapy.Field() #南邮新闻时间 news_url = scrapy.Field() #南邮新闻的详细链接
至于为什么每一句都用scrapy.Field(),这个等请关注我的后续教程,现在只要记住按照以上的格式来添加新的要提取的属性就可以了~。
3. 编写 spider
spider是爬虫的主体,负责处理requset response 以及url等内容,处理完之后交给pipelines进行进一步处理。
设置完items之后,就在spiders目录下新建一个njuptSpider.py文件,内容如下:
# -*- coding: utf-8 -*- import scrapy from njupt.items import NjuptItem import logging class njuptSpider(scrapy.Spider): name = "njupt" allowed_domains = ["njupt.edu.cn"] start_urls = [ "http://news.njupt.edu.cn/s/222/t/1100/p/1/c/6866/i/1/list.htm", ] def parse(self, response): news_page_num = 14 page_num = 386 if response.status == 200: for i in range(2,page_num+1): for j in range(1,news_page_num+1): item = NjuptItem() item[\'news_url\'],item[\'news_title\'],item[\'news_date\'] = response.xpath( "//div[@id=\'newslist\']/table[1]/tr["+str(j)+"]//a/font/text()" "|//div[@id=\'newslist\']/table[1]/tr["+str(j)+"]//td[@class=\'postTime\']/text()" "|//div[@id=\'newslist\']/table[1]/tr["+str(j)+"]//a/@href").extract() yield item next_page_url = "http://news.njupt.edu.cn/s/222/t/1100/p/1/c/6866/i/"+str(i)+"/list.htm" yield scrapy.Request(next_page_url,callback=self.parse_news) def parse_news(self, response): news_page_num = 14 if response.status == 200: for j in range(1,news_page_num+1): item = NjuptItem() item[\'news_url\'],item[\'news_title\'],item[\'news_date\'] = response.xpath( "//div[@id=\'newslist\']/table[1]/tr["+str(j)+"]//a/font/text()" "|//div[@id=\'newslist\']/table[1]/tr["+str(j)+"]//td[@class=\'postTime\']/text()" "|//div[@id=\'newslist\']/table[1]/tr["+str(j)+"]//a/@href").extract() yield item
其中
-
name为爬虫名称,在后面启动爬虫的命令当中会用到。 -
allowed_domains为允许爬虫爬取的域名范围(如果连接到范围以外的就不爬取) -
start_urls表明爬虫首次启动之后访问的第一个Url,其结果会被自动返回给parse函数。4. -
parse函数为scrapy框架中定义的置函数,用来处理请求start_urls之后返回的response,由我们实现 -
news_page_num = 14和page_num = 386别表示每页的新闻数目,和一共有多少页,本来也可以通过xpath爬取下来的,但是我实在是对我们学校的网站制作无语了,html各种混合,于是我就偷懒手动输入了。 -
之后通过
item = NjuptItem()来使用我们之前定义的item,用来存储新闻的url、标题、日期。(这里面有一个小技巧就是通过|来接连xpath可以一次返回多个想要抓取的xpath) -
通过
yield item来将存储下来的item交由后续的pipelines处理 -
之后通过生成
next_page_url来通过scrapy.Request抓取下一页的新闻信息 -
scrapy.Request的两个参数,一个是请求的URL另外一个是回调函数用于处理这个request的response,这里我们的回调函数是parse_news -
parse_news里面的步骤和parse差不多,当然你也可以改造一下parse然后直接将其当做回调函数,这样的话一个函数就ok了
4. 编写 pipelines
初次编写可以直接编辑njupt目录下的pipelines.py文件。pipelines主要用于数据的进一步处理,比如类型转换、存储入数据库、写到本地等。
本爬虫pipelines如下:
import json class NjuptPipeline(object): def __init__(self): self.file = open(\'njupt.txt\',mode=\'wb\') def process_item(self, item, spider): self.file.write(item[\'news_title\'].encode("GBK")) self.file.write("\n") self.file.write(item[\'news_date\'].encode("GBK")) self.file.write("\n") self.file.write(item[\'news_url\'].encode("GBK")) self.file.write("\n") return item
其实pipelines是在每次spider中yield item 之后调用,用于处理每一个单独的item。上面代码就是实现了在本地新建一个njupt.txt文件用于存储爬取下来的内容。
5. 编写 settings.py
settings.py文件用于存储爬虫的配置,有很多种配置,由于是入门教程,不需要配置很多,我们这里就添加一下刚才编写的pipelines就行了。文件内容如下。
BOT_NAME = \'njupt\' SPIDER_MODULES = [\'njupt.spiders\'] NEWSPIDER_MODULE = \'njupt.spiders\' ITEM_PIPELINES = { \'njupt.pipelines.NjuptPipeline\':1, }
6. 启动爬虫与查看结果
以上步骤全部完成之后,我们就启动命令行,然后切换运行目录到njupt的spider目录下,通过以下命令启动爬虫
scrapy crawl njupt
经过一段时间的风狂爬取,爬虫结束。会报一些统计信息
最后让我们来查看一下爬取成果
至此,大功告成~
scrapy入门教程3:scrapy的shell命令
0. 基本环境说明
-
本文截图及运行环境均在Win8上实现(是的,我放假回家了,家里的机器是win8的没有办法),但基本步骤与win 7环境基本相同。(应该把~)ps:我后来换了台win7的电脑,所以这篇文章的环境是win8和win7的结合体~,哇哈哈~,然而这并没有什么卵用~
-
scrapy版本为1.0.3
-
这篇文章基本就是很无耻的翻译了一下官方文档顺便添加了一点自己的理解
-
参考文献以及下载链接:
-
喜欢的就点推荐+收藏把~这样我会把我知道的都写出来的,哇哈哈~
-
我用的操作系统是64位的,但是python用的是32位的,因为32位的包比较全,但是我最近在往64位的服务器上移植,到时候有问题我会及时添加的。
1. scrapy的shell命令详解
1.1 命令概览
首先可以通过以下命令来查看所有scrapy可用的命令类型:
scrapy -h
scrapy目前的命令可以分为项目命令和全局命令两大类,共14种(嗯 ,我认真的数了两遍),分布也极其对称,项目级命令7种全局命令7种(嗯,我又认真的数了一遍)。
分别是:
全局命令
-
startproject
-
settings
-
runspider
-
shell
-
fetch
-
view
-
version
项目命令
-
crawl
-
check
-
list
-
edit
-
parse
-
genspider
-
bench
哇哈哈,然我们接着开始一一学习一下这些命令吧,有些命令好用的不要不要的哦~
1.2 全局命令解析
1.2.1 startproject 创建项目命令
-
基本语法:
scrapy startproject <project_name> -
是否需要项目存在:当然是不需要咯~
其实这个命令我们在之前的教程当中也用过了,应该不陌生,就是在创建一个名为project_name的爬虫框架,供我们调教(猥琐脸)。是创建爬虫项目开天辟地的第一步哟~。
用例
scrapy startproject njupt
#嗯,我无耻的修改了官方的例子,在运行命令行的目录下面创建了一个名为njupt的文件夹,里面存放了一个名为njupt的scrapy框架
1.2.2 settings 查看配置文件参数命令
-
基本语法:
scrapy settings [options] -
是否需要项目存在:当然是不需要咯~(这是官方写的,貌似有点问题)
嘛这个命令是用来查看项目参数的。官方文档说不需要项目,经过本人测试,如果在项目目录下,就会显示出项目的settings.py里面对应的项目的内容,如果实在项目目录之外,貌似会返回一个scrapy的默认值,我个人建议大家在项目目录下使用这个命令来查看settings.py里面的内容就ok了。
用例
scrapy settings --get BOT_NAME
1.2.3 runspider 运行爬虫命令
-
基本语法:
scrapy runspider <spider_file.py> -
是否需要项目存在:当然是不需要咯~
貌似这个命令是不依托一个scrapy项目而直接运行一个爬虫的命令。弱弱的说一句,这种没有settings没有pipelines的爬虫真的好么
用例
scrapy runspider njupt.py
1.2.4 shell 创建一个shell环境用于调试response的命令(很重要!!!)
-
基本语法:
scrapy shell [url] -
是否需要项目存在:当然是不需要咯~
这个命令真的很重要啦~,主要目的是创建一个shell环境用于调试response的命令(嗯,和标题一模一样),因为她太重要了,所以我临时决定回来专门写一篇文章来介绍这个命令,迫不及待的同学去翻官方文档吧~(其实我是累了,因为我一边码字一遍在重装电脑而且现在也半夜十二点多了~说好的早睡又泡汤的)
用例:
scrapy shell http://www.njupt.edu.cn
1.2.5 fetch 显示爬取过程
-
基本语法:
scrapy fetch [url] -
是否需要项目存在:貌似有没有都行
这个命令其实是在标准输出中显示调用一个爬虫来爬取指定的url的全过程。
要注意的一点是,如果是在一个项目目录下使用这个命令则会默认调用这个项目当中的爬虫,如果在项目目录之外使用这个命令,则会调用scrapy默认的爬虫来爬取。所以有没有项目存在都能运行。
用例:
scrapy fetch http://www.njupt.edu.cn
#会显示抓取的过程,以及抓取的html的内容
scrapy fetch --nolog --headers http://www.njupt.edu.com/
#可以添加一些参数来,观察各种信息,如添加个:
--nolog 可以忽略很多烦人的日志
--headers 用来查看请求时的头部信息
1.2.6 view 查看页面内容命令
-
基本语法:
scrapy view [url] -
是否需要项目存在:无需项目存在
当你对于某些信息死也提取不出来的时候就要考虑使用一下使用这个view了,这个命令是给你下载一个页面并用浏览器打开,目的是让你对比一下scrapy"看到"的页面和你通过浏览器看到的页面有什么不同,这个对于某些动态生成的网页很有作用!但是这里有个坑大家注意一下,我在Win7环境下,使用这个命令的时候在下载对应网页的同时用浏览器打开(目测纯命令行无图形界面的Linux因该不会自动打开浏览器),此时里面的ajax因为有了浏览器打开,又被执行了,所以通过浏览器打开的页面应该和你正常访问的网页并无二致,但并不是真正scrapy看到的网页。如何看到真正的网页内?很简单啦,找到原始地址用sublime打开就是啦~。原始地址就在浏览器的地址栏里哦~
用例:
scrapy view http://item.jd.com/1319191.html
#嗯,我背叛了大njupt,因为我们学校的网站太牛X没有使用ajax,所以我就用大JD做例子了。
1.2.7 version 显示版本信息
-
基本语法:
scrapy version [-v] -
是否需要项目存在:无需项目存在
此命令很简单,就是显示scrapy的版本,如果加上-v命令则还会显示Python, Twisted和平台的信息,貌似对于bug寻找和报告很有帮助!
1.3 项目命令解析
1.3.1 genspider 通过模板生成爬虫
-
基本语法:
scrapy genspider [-t template] <name> <domain> -
是否需要项目存在:项目命令嘛,果断需要~
这个命令主要是帮助我们在编写多个爬虫的时候,利用现有爬虫来快速生成新的爬虫,当然这不是唯一创建新爬虫的方式,骚年,不嫌累的话可以自己重新敲一个~
用例:
scrapy genspider -l
通过添加参数-l来查看现有的爬虫模板
scrapy genspider -d basic
通过添加参数-d和模板名称来查看现有模板的内容,嘛如果实在linux环境下会比较好用,我等在win下面混的菜鸟还是右键用sublime来查看内容吧
scrapy genspider -t basic example example.com
这就是激动人心的生成爬虫的方式了,通过参数-t后面紧接着的内容是模板名称 新爬虫的名称 新爬虫允许爬取的域名,貌似一般爬虫名称基本都是域名主体呢~,聪明的同学也知道这里新爬虫名称 新爬虫允许爬取的域名分别对应的就是之前上一篇教程提到的name和allowed_domains这两个参数咯。
1.3.2 crawl 启动爬虫命令
-
基本语法:
scrapy crawl <spider> -
是否需要项目存在:项目命令嘛,果断需要~
这个命令是很激动人心的,每次写完爬虫就迫不及待的一试,大家在上篇教程中想必也已经实验过了。不过貌似一次只能跑一个爬虫,想运行多个爬虫怎么办呢?我现在想到的两个解决方案
1.自己写一个bat或者shell脚本
2.自己添加一个scrapy的shell命令(没错,听起来屌飞了,我会在以后的教程中告诉你怎么做的,想看的以后的教程,哼哼~,我才不会请你点推荐加收藏呢~)
用例:
scrapy crawl njupt #咩哈哈,启动njupt爬虫吧骚年~
1.3.3 check 检查爬虫完整性
-
基本语法:
scrapy check [-l] <spider> -
是否需要项目存在:项目命令嘛,果断需要~
这个命令官方写的是Contect检查然后就没了,我在win7下面试了一下,能检查出一部分错误,但是后面加一个-l参数貌似没什么用啊,没有显示出官方文档例子里面的spider列表和函数列表,倒是有一堆warning,我回来研究研究一下源码看看把,这个命令目前就是检查一些语法、import和warning等错误,逻辑错误肯定是查不出来的啦~
用例:
scrapy check njupt
1.3.4 list 查看爬虫列表命令
-
基本语法:
scrapy list -
是否需要项目存在:项目命令嘛,果断需要~
这个命令就是查看一下这个项目里面目前有哪些爬虫~,写了很多的爬虫之后打这个命令有一种阅兵的快感呢~,一般linux环境下使用较多~
用例:
scrapy list
1.3.5 edit 编辑爬虫命令
-
基本语法:
scrapy edit <spider> -
是否需要项目存在:项目命令嘛,果断需要~
典型的在linux里面用的高大上命令啊,输入此命令可以立刻调取settings.py中的editor指定的编辑器来打开爬虫进行编辑(是的,settings.py里面还能配这么屌的参数我也很震惊)。顺便说一句我的win7系统运行之后直接报错...伤心啊
用例:
scrapy edit njupt
1.3.6 parse
-
基本语法:
scrapy parse <url> [options] -
是否需要项目存在:项目命令嘛,果断需要~
这方法适合测试自己写的spider和后续各种组建如:pipeline等组合使用的情况,我一般用来测试自己编写的spider(在没有见过这个命令之前我一直是用crawl命令来测试的...悲剧啊)。
支持的参数倒是蛮丰富的:
-
--spider=SPIDER: 没有指定spider的情况下其程序搜索,用这个选项可以强行指定某个spider -
--a NAME=VALUE: 用来设定spider需要的参数,可以多个 -
--callback或-c: 指定spider里面用于处理response的函数,没有强行制定的话,默认使用parse函数 -
--pipelines:用来指定后续的pipelines,可以灵活定制哦~ -
--rules或-r: 通过CrawlSpider设定的规则来选取对应的函数当作解析response的回调函数 -
--noitems: 不显示抓取的items -
--nolinks: 不显示提取的链接 -
--nocolour: 输出的结果不要高亮显示(这个选项还是不要用得好) -
--depth或-d: 设置爬取深度,默认为1哦~ -
--verbose或-v: 显示被爬取的每层的相关信息
用列:
scrapy parse http://www.njupt.edu.cn
1.3.7 bench 硬件测试命令
-
基本语法: scrapy bench
-
是否需要项目存在:不需要
这个命令我个人理解就是对你的硬件做一个爬虫的压力测试,看看不考虑网络的情况下你的硬件究竟能将这个爬虫运行的多快。当然这个有点理论速度的味道,实际上你爬起来不可能这个么快。姑且算是告诉你硬件的瓶颈的方法吧。不过我win7上运行了貌似没有什么用,没有出现官方说好的各种参数,回来有空还要仔细研究一下啊。
用例:
scrapy bench
我终于写完了,喜欢的就收藏+推荐一下吧,这样我就会更有动力写新的教程了,哇哈哈~
scrapy入门教程4:代理模块(1)
0. 基本环境说明
-
本文截图及运行环境均在Win7上实现(没错,我有折腾回来了,MAC上面的兄弟就照葫芦画瓢吧~)
-
scrapy版本为1.0.3
-
参考文献以及下载链接:
-
请按顺序阅读本教程
0.1前言
教程已经三个月没有更新了,原因是老板接了一个中兴的大数据项目,我被拉过去负责这个项目了,有兴致回来再来一发Spark教程吧~,最近终于有时间接着稍微写一些了,我一定要将写博客这个活动坚持下去,不论断了多少次我都会续上的~,本来准备写一些分布式爬虫的内容,但是还在调试阶段,等搞完之后一起写出来,咩哈哈~
本篇内容主要是教各位怎么初期配置一下scrapy的代理,其实后续有很多很麻烦的事情(比如如何构建代理池、如何获取大量代理、如何测试代理可用性等)。有空我会慢慢写的~(我需要读者的支持啊~粉我一下吧,不粉的话推荐一下也行啊~大家都不容易是吧~)
1. 简述
在scrapy中专门有一个模块Downloader Middleware来实现scrapy爬虫中请求和相应的某些通用功能,比如我们这次要用到的代理功能,就是通过其子模块HttpProxyMiddleware来实现的,至于Downloader Middleware的其他子模块,我以后有空会一一介绍的,现在大家只要知道这个模块的基本含义就行了。
2.代理配置
2.1 创建代理模块
首先我们现在njupt目录下面新建一个名称为middlewares.py的文件,文件内容如下:
import base64 class ProxyMiddleware(object): def process_request(self, request, spider): request.meta[\'proxy\'] = "http://IP地址:端口号" proxy_user_pass = "用户名:帐号" encoded_user_pass = base64.encodestring(proxy_user_pass) request.headers[\'Proxy-Authorization\'] = \'Basic \' + encoded_user_pass
其中
-
process_request这个方法是自带的,是在每个请求之前都会自动执行一下,借此来修改参数 -
request.meta[\'proxy\']直接通过这个属性直接设置代理,填的是IP地址和端口号,如http://218.200.66.196:8080,一般你搞来的代理都会有着两个东西,直接填上去就好~ -
如果你搞来的代理还需要账号和密码的话,我们就需要给
proxy_user_pass赋值,形如root:12345。 -
为了让你的代理帐号密码能良好运行,我们还需要
base64.encodestring这个函数来帮一下忙,对你的代理帐号密码进行编码。 -
最后将编码过后的函数赋值给http头中的
Proxy-Authorization参数即可。
注意:以上3~5步,如果代理没有帐号密码的话就不要折腾了。
建立完毕之后文件目录结构如下:
|---- njupt | |---- njupt | |---- __init__.py | |---- items.py #用来存储爬下来的数据结构(字典形式) | |---- middlewares.py #用来配置代理 | |---- pipelines.py #用来对爬出来的item进行后续处理,如存入数据库等 | |---- settings.py #爬虫配置文件 | |---- spiders #此目录用来存放创建的新爬虫文件(爬虫主体) | |---- __init__.py | |---- scrapy.cfg #项目配置文件
2.2 修改配置文件
代理文件创建完毕之后,需要修改配置文件settings.py,并在添加如下内容:
DOWNLOADER_MIDDLEWARES = { \'njupt.middlewares.ProxyMiddleware\': 100, }
嘛,就是添加一下大的配置模块Downloader Middleware,外加配置一个子模块HttpProxyMiddleware嘛~
2.3 结果测试
其实这个配置代理重点之一就是测试环节了,我这里给各位提供一种测试思路直接请求查看自身IP以及区域的网站即可,如(http://ip.filefab.com/),根据其返回的结果(图2-1与图2-2所示)来判断是否成功。
图2-1 生成的文件
图2-2 代理的具体信息
具体测试代码可参考基本说明中的附件代码。咱们下期见~
https://segmentfault.com/a/1190000003967348