抓取scrapy中文文档 第一个Scrapy项目实现
使用Scrapy这个python的网络爬虫框架抓取Scrapy中文文档
开发第一步:新建项目scrapy startproject myfirst
目录结构:
myfirst
│ scrapy.cfg Scrapy项目配置文件 │ └─myfirst Scrapy项目代码存放目录 │ items.py 存储从抓取的网页中需要保存的数据,再其中指定要存储的域 │ pipelines.py 管道文件,用于存储从抓取的网页中解析出的其他页面的url,相当于任务队列 │ settings.py 爬虫配置文件 │ __init__.py │ └─spiders 存放爬虫定义的目录 __init__.py
编写items.py文件:
from scrapy.item import Item, Field
import sys
default_encoding = 'cp936'
if sys.getdefaultencoding() != default_encoding:
reload(sys)
sys.setdefaultencoding(default_encoding)
class DmozItem(Item):
title = Field()
link = Field()
desc = Field()
在items.py中,定义了三个Field用于指定我们要从抓取的网页数据中抽取的数据
编写爬虫程序myfirstSpider.py,在spiders目录下:
#encoding: utf-8
from scrapy.spider import BaseSpider
from scrapy.selector import HtmlXPathSelector
from scrapy.http import Request
from myfirst.items import MyfirstItem
import os
#设置默认编码
import sys
default_encoding = 'cp936'
if sys.getdefaultencoding() != default_encoding:
reload(sys)
sys.setdefaultencoding(default_encoding)
class ScrapyDocSpider(BaseSpider):
name = 'ScrapyDoc' #设置爬虫的标识名
allowed_domains = ['scrapy-chs.readthedocs.org'] #指定爬虫在哪个域中抓取数据
start_urls = ['http://scrapy-chs.readthedocs.org/zh_CN/latest'] #设置爬虫抓取的入口url地址
def parse(self,response):
if response.url.split("/")[-1] == '':
filename = response.url.split("/")[-2]
else :
dirname = response.url.split("/")[-2]
#判断是否有此目录,如果没有就新建
if os.path.isdir(dirname) == False:
os.mkdir(dirname)
filename = '/'.join(response.url.split("/")[-2:])
#保存文件
open(filename,'wb').write(response.body)
sel = HtmlXPathSelector(response) #创建Html解析器
sites = sel.select('//li[@class="toctree-l1"]')
for site in sites:
item = MyfirstItem()
item['title'] = site.select('a/text()').extract()
#生成连接 begin ,因为从页面提取的连接都是相对地址
link = site.select('a/@href').extract()[0]
url = response.url
#地址形式是否为 ../spiders.html 这种形式,需要回到上级地址
if link.split('/')[0] == '..':
url2 = '/'.join(url.split('/')[0:-2]) + '/' + '/'.join(link.split('/')[1:])
else:
url2 = '/'.join(url.split('/')[0:-1]) + '/' + link
item['link'] = [url2]
#生成连接 end
yield item
#返回多个request
yield Request(url=url2,callback=self.parse)
return
爬虫将从start_urls列表中的url开始,将每一个url封装成Request对象,并将parse方法作为回调函数,将返回的Response作为参数传入,response即返回的响应,其中包含了headers和body,headers即响应的头部信息,body即响应的正文信息(html静态页面或json\xml等。。)
在parse方法中即可以利用html/xml解析器通过xpath抓取特定节点的数据,存储到items.py中的指定field中
并将解析到的页面中的其他url转成request返回,交给spider,由spider存放到pipeline队列中scheduler的调度,继续抓取下一个页面
回到项目主目录,新建doc目录,切到doc目录,doc作为下载的文档存放目录
运行爬虫:
scrapy crawl ScrapyDoc
启动名为ScrapyDoc的爬虫。。。
开始抓取页面 。。。。。。
将从页面中解析的数据保存到item中
scrapy crawl ScrapyDoc -o myfirst.json -t json
最后items中定义的域中的数据将作为json数据存储到myfirst.json文件中