赞
踩
scrapy框架是一款基于python的爬虫框架,从这个框架的项目构造形式,我们可以看出它主要分为spider.py
pipeline.py
item.py
decorator.py
middlewares.py
setting.py
.下面主要谈一谈spider.py pipeline.py item.py and setting.py。
简单来说,item 就相当于 java 中的 javabean 的作用,spider.py具体负责爬数据的工作,并且交给对应的 pipeline.py 来处理数据.setting.py 进行一些全局的配置,方便读取.
从名字可以看出 spider–蜘蛛,说明这个文件就是具体执行爬虫任务的.
# -*- coding: utf-8 -*- import scrapy from 项目名称(随便起).items import 项目名称(随便起)Item from 项目名称(随便起) import pipelines import sys import urllib from scrapy.selector import Selector # from 项目名称(随便起).spiders.dateutil import dateutil import random import math import 项目名称(随便起).my_server as my_server import logging class testspidertest(scrapy.Spider): name = "testspider" allowed_domains = [""] date = "" pageNumber = 0 ptype = "fmsq" key = name def __init__(self): self.pageNumber = 0 self.date = "PD='2016.06.22'" pipeline = set([ pipelines.JsonPipeline2, # pipelines.MongoDBFmsqPipeline, ]) def start_requests(self): # logging.info("=========================start====================") # util = dateutil() # dateList = util.getAllWed() # for index,d in enumerate(dateList): # dateList[index] = "公开(公告)日="+d # for d in dateList: # print d self.date = "PD=2016.06.22" # get list of patent page by page # v=self.date+self.ptype+str(1) # my_server.r.sadd(self.key, v) # print "+++++++++++++" + self.date + "++++++++++++++++" yield scrapy.FormRequest("http://epub.sipo.gov.cn/pam.action", formdata={ 'strSources': 'pip', 'strWhere': 'PN=CN105765909A', 'recordCursor': '0'}, dont_filter=True, callback=self.post_over) pass def post_over(self, response): logging.info("23333") hxs = Selector(response) # scrapy.shell.inspect_response(response,self) logging.info("still fuck can't get ") tttt = hxs.xpath('//div[@class="main"]/dl/dd/ul/li[3]/a/@href').extract()[0] print "=============" + tttt return tttt
我们看这个文件,首先他继承了scrapy.spider
,并且重写了一些方法,先看变量,name
就是这个spider
的 name
,allowed_domains
这个是 spider
要求设置的一个变量,表示允许爬虫爬的网站.pipeline = set....
这个设置了该 spider 过后,应该转向哪一个 pipeline
来处理数据.根据官方文档的解释,start_requests
方法和 start-url
变量的作用是一样的,都是这是爬虫开爬的 url,由于我们这里用的是 post 的方法,参数较多,后期还会更改,所以用start_requests
其中
yield scrapy.FormRequest("http://epub.sipo.gov.cn/pam.action",
formdata={
'strSources': 'pip', 'strWhere': 'PN=CN105765909A', 'recordCursor': '0'},
dont_filter=True,
callback=self.post_over)
(ps:格式有点乱了…)
formdata
是 post 传递的参数,dont_filter
的意思是强制爬这个网址,不要过滤,换言之,就是不管他是否在allow_domain
下都爬.callback 是一个回调函数,指的是如果爬完该网页,应该去哪个回调函数来处理.关于回调函数是什么意思,就不解释了.(其实是因为本人的理解也不是很深,只知皮毛..)
看代码,post_over
就是我们的回调函数
下面看这个函数,response
就是我们 request
的返回,我们通过Selector()
这个函数可以拿到一个搜索器hxs
,通过他可以用 xpath 或者 css 来访问对应的 html 元素.并把这些元素放到 item 中,返回 return
出去.
return
的 item 会进入到对应的 pipeline 里,我们来看对应的代码.
from scrapy import signals
import json
import codecs
import pymongo
from scrapy.conf import settings
from scrapy.exceptions import DropItem
# from scrapy.pipelines.images import ImagesPipeline
import datetime
import logging
# import 项目名称(随便起).settings as ipsettings
from 项目名称(随便起).decorator import check_spider_pipeline
#写图片需要的库
import urllib
import os
class ImageDownloadPipeline(object):
def process_item(self, item, spider):
if item['image_urls'] == '':
DropItem("no picture")
# print "*********************"
# print spider.date
# print "*********************"
dir_path = settings['IMAGES_STORE'] + spider.name + '/' + spider.date + '/full/'
dir_thumb_path = settings['IMAGES_STORE'] + spider.name + '/' + spider.date + '/thumb/'
if not os.path.exists(dir_path):
os.makedirs(dir_path)
if not os.path.exists(dir_thumb_path):
os.makedirs(dir_thumb_path)
us = item['authId'] + '.jpg'
file_path = dir_path + us
file_thumb_path = dir_thumb_path + us
if os.path.exists(file_path):
pass
else:
urllib.urlretrieve("http://epub.sipo.gov.cn/" + item['image_urls'],file_path)#写图片的
urllib.urlretrieve("http://epub.sipo.gov.cn/" + item['image_thumb_urls'],file_thumb_path)#写图片的
# print "=======================" +item['image_urls']
item['image_urls'] = file_path
item['image_thumb_urls'] = file_thumb_path
return item`
我们就以这个 pipeline 作为例子,其中process_item
是必须的方法,里面有三个参数self item spider .self
不必说了,就是指这个class 自身,通过他可以访问 class 的全局变量,item 指的是我们传进来的 item,即刚才 spider 返回的 item.spider 是调用这个 pipeline 的 spider,从这个变量,我们可以获得 spider 的一些信息,这就实现了两个模块的通信,以上代码的作用是下载图片并修改图片的路径为本地路径.当然通过pipeline 也可以把所获得的数据存到数据库中,或者本地文件里…
setting.py 中定义了需要用到的路径,项目名称(随便起),pipeline 以及 scrapy 需要的设置等.详细的内容可以参考官方的文档.简单举了声明 pipeline 的例子:
ITEM_PIPELINES = {
# '项目名称(随便起).pipelines.JsonPipeline1' : 300,
# '项目名称(随便起).pipelines.JsonPipeline2' : 300,
'项目名称(随便起).pipelines.ImageDownloadPipeline' : 80,
'scrapy_redis.pipelines.RedisPipeline':100, #自动加spider2:item
'项目名称(随便起).pipelines.MongoDBFmgbPipeline': 201,
}
我们所有要启用的 pipeline 都必须这么声明,可以很清晰的看到冒号:
前面的是 pipeline 的路径,后面是1-1000的数字,代表优先级,数字越小,优先级越高.我们可以合理的分配优先级,使得对应的 pipeline 按序执行.
其他的几个文件,还没有研究,只知道middlewares.py
可以设置需要的代理,用来防止爬虫被检测到.
总结一下,就像许多博文曾经说的,scrapy 框架的思路还是很清晰的,这是他的一大优点,本人之前没有学习过 python,所以初次接触,走了一些坑,而且在写代码的时候也给自己挖了很多坑..故作此记录.
本文原创,如需转载,请联系,如有任何地方侵权,请联系. 如有错误,欢迎交流…
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。