开发环境
mac
pthon 3.6以上
开发工具:pycharm
mogodb 3.6.5
mongo客户端工具robo mongo
Scrapy简介
Scrapy是一个功能完善的爬虫框架,提供了很多强大的特性来使得爬取更为简单高效, 例如:
HTML, XML源数据 选择及提取 的内置支持
提供了一系列在spider之间共享的可复用的过滤器(即 Item Loaders),对智能处理爬取数据提供了内置支持。
通过 feed导出 提供了多格式(JSON、CSV、XML),多存储后端(FTP、S3、本地文件系统)的内置支持
提供了media pipeline,可以 自动下载 爬取到的数据中的图片(或者其他资源)。
高扩展性。您可以通过使用 signals ,设计好的API(中间件, extensions, pipelines)来定制实现您的功能。
-
内置的中间件及扩展为下列功能提供了支持:
cookies and session 处理
HTTP 压缩
HTTP 认证
HTTP 缓存
user-agent模拟
robots.txt
爬取深度限制
其他
针对非英语语系中不标准或者错误的编码声明, 提供了自动检测以及健壮的编码支持。
支持根据模板生成爬虫。在加速爬虫创建的同时,保持在大型项目中的代码更为一致。详细内容请参阅 genspider 命令。
针对多爬虫下性能评估、失败检测,提供了可扩展的 状态收集工具 。
提供 交互式shell终端 , 为您测试XPath表达式,编写和调试爬虫提供了极大的方便
提供 System service, 简化在生产环境的部署及运行
内置 Web service, 使您可以监视及控制您的机器
内置 Telnet终端 ,通过在Scrapy进程中钩入Python终端,使您可以查看并且调试爬虫
Logging 为您在爬取过程中捕捉错误提供了方便
支持 Sitemaps 爬取
具有缓存的DNS解析器
创建项目
我们来做一个爬虫,来爬取http://www.iteye.com/news下的信息,并存储到mongodb中。
首先在本地项目目录下执行以下操作
scrapy startproject myspider --nolog #myspider为project_name
项目结构及说明
-
scrapy.cfg
: 项目的配置文件 -
myspider/
: 该项目的python模块。之后您将在此加入代码。 -
myspider/items.py
: 项目中的item文件. -
myspider/pipelines.py
: 项目中的pipelines文件. -
myspider/settings.py
: 项目的设置文件. -
myspider/spiders/
: 放置spider代码的目录.
定义抓取的数据结构Scrapy Items
items.py增加代码:
class NewsItem(scrapy.Item):
title = scrapy.Field()
link = scrapy.Field()
desc = scrapy.Field()
publish_time = scrapy.Field()
编写Spider
创建iteye_spider.py文件
执行爬取命令
在项目目录下,命令行执行
scrapy crawl iteye # iteye为spider name
为了将信息输出到pycharm控制台,我们写一个main.py,直接运行这个文件就可以了
from scrapy import cmdline
cmdline.execute('scrapy crawl iteye -o iteye_news.json'.split())
这样抓取的数据都写入了iteye_news.json中了,默认编码为Unicode。
存储数据到mongodb
- 修改settings.py
# 打开数据管道配置
ITEM_PIPELINES = {
'myspider.pipelines.MyspiderPipeline': 300,
}
# mogo的基本配置信息
mongo_host = '127.0.0.1'
mongo_port = 27017
mongo_db_name = 'iteye'
mongo_db_collection = 'iteye_news'
- 编写pipeline.py
这里用到了pymogo包
class MyspiderPipeline(object):
def __init__(self):
# 创建数据库连接
host = mongo_host
port = mongo_port
dbname = mongo_db_name
sheetname = mongo_db_collection
client = pymongo.MongoClient(host=host,port=port)
mydb = client[dbname]
self.post = mydb[sheetname]
def process_item(self, item, spider):
#将数据写入mongodb中
data = dict(item)
self.post.insert(data)
return item
mongo默认安装配置即可。
-
查看执行后的效果
monogo中创建了iteye数据库,查看抓取的数据。
db.getCollection('iteye_news').find({})
代理中间件的编写
为了隐藏爬虫程序的身份,避免爬虫程序的ip直接被网站禁用,通常可以采取ip代理和随机user agent两种方式。
ip代理中间件
修改middlewares.py
# ip代理的设置
class my_proxy(object):
def process_request(self,request,spider):
# 代理服务器网址和ip
request.meta['proxy'] = ''
# 代理服务的用户和密码
proxy_name_pwd = b''
# 对用户密码加密
encode_name_pwd = base64.b64encode(proxy_name_pwd)
# 设置代理服务
request.headers['Proxy-Authorization'] = 'Basic' + encode_name_pwd.decode()
user agent代理中间件
在Python中,如果不设置User Agent,程序将使用默认的参数,那么这个User Agent就会有Python的字样,如果服务器检查User Agent,那么没有设置User Agent的Python程序将无法正常访问网站。
修改middlewares.py
# 设置user agent
class my_user_agent(object):
def process_request(self,request,spider):
USER_AGENT_LIST=[
'MSIE (MSIE 6.0; X11; Linux; i686) Opera 7.23',
'Opera/9.20 (Macintosh; Intel Mac OS X; U; en)',
'Opera/9.0 (Macintosh; PPC Mac OS X; U; en)',
'iTunes/9.0.3 (Macintosh; U; Intel Mac OS X 10_6_2; en-ca)',
'Mozilla/4.76 [en_jp] (X11; U; SunOS 5.8 sun4u)',
'iTunes/4.2 (Macintosh; U; PPC Mac OS X 10.2)',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:5.0) Gecko/20100101 Firefox/5.0',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:9.0) Gecko/20100101 Firefox/9.0',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:16.0) Gecko/20120813 Firefox/16.0',
'Mozilla/4.77 [en] (X11; I; IRIX;64 6.5 IP30)',
'Mozilla/4.8 [en] (X11; U; SunOS; 5.7 sun4u)'
]
self.choice = random.choice(USER_AGENT_LIST)
agent = random.choice(USER_AGENT_LIST)
request.headers['User-Agent'] = agent
开启中间件配置
修改setting.py
# 开启代理设置,543位中间件的顺序号,数字小的优先
DOWNLOADER_MIDDLEWARES = {
'myspider.middlewares.my_user_agent': 543,
'myspider.middlewares.my_proxy': 544,
}
参考资料
python基础教程:http://www.runoob.com/python/python-tutorial.html
Scrapy入门教程:https://scrapy-chs.readthedocs.io/zh_CN/0.24/intro/tutorial.html