Python的Scrapy爬虫框架简单学习笔记
一、简单配置,获取单个网页上的内容。
(1)创建scrapy项目
scrapystartprojectgetblog
(2)编辑items.py
#-*-coding:utf-8-*- #Defineherethemodelsforyourscrapeditems # #Seedocumentationin: #http://doc.scrapy.org/en/latest/topics/items.html fromscrapy.itemimportItem,Field classBlogItem(Item): title=Field() desc=Field()
(3)在spiders文件夹下,创建blog_spider.py
需要熟悉下xpath选择,感觉跟JQuery选择器差不多,但是不如JQuery选择器用着舒服(w3school教程:http://www.w3school.com.cn/xpath/ )。
#coding=utf-8
fromscrapy.spiderimportSpider
fromgetblog.itemsimportBlogItem
fromscrapy.selectorimportSelector
classBlogSpider(Spider):
#标识名称
name='blog'
#起始地址
start_urls=['http://www.cnblogs.com/']
defparse(self,response):
sel=Selector(response)#Xptah选择器
#选择所有含有class属性,值为‘post_item'的div标签内容
#下面的第2个div的所有内容
sites=sel.xpath('//div[@class="post_item"]/div[2]')
items=[]
forsiteinsites:
item=BlogItem()
#选取h3标签下,a标签下,的文字内容‘text()'
item['title']=site.xpath('h3/a/text()').extract()
#同上,p标签下的文字内容‘text()'
item['desc']=site.xpath('p[@class="post_item_summary"]/text()').extract()
items.append(item)
returnitems
(4)运行,
scrapycrawlblog#即可
(5)输出文件。
在settings.py中进行输出配置。
#输出文件位置 FEED_URI='blog.xml' #输出文件格式可以为json,xml,csv FEED_FORMAT='xml'
输出位置为项目根文件夹下。
二、基本的--scrapy.spider.Spider
(1)使用交互shell
dizzy@dizzy-pc:~$scrapyshell"http://www.baidu.com/"
2014-08-2104:09:11+0800[scrapy]INFO:Scrapy0.24.4started(bot:scrapybot)
2014-08-2104:09:11+0800[scrapy]INFO:Optionalfeaturesavailable:ssl,http11,django
2014-08-2104:09:11+0800[scrapy]INFO:Overriddensettings:{'LOGSTATS_INTERVAL':0}
2014-08-2104:09:11+0800[scrapy]INFO:Enabledextensions:TelnetConsole,CloseSpider,WebService,CoreStats,SpiderState
2014-08-2104:09:11+0800[scrapy]INFO:Enableddownloadermiddlewares:HttpAuthMiddleware,DownloadTimeoutMiddleware,UserAgentMiddleware,RetryMiddleware,DefaultHeadersMiddleware,MetaRefreshMiddleware,HttpCompressionMiddleware,RedirectMiddleware,CookiesMiddleware,ChunkedTransferMiddleware,DownloaderStats
2014-08-2104:09:11+0800[scrapy]INFO:Enabledspidermiddlewares:HttpErrorMiddleware,OffsiteMiddleware,RefererMiddleware,UrlLengthMiddleware,DepthMiddleware
2014-08-2104:09:11+0800[scrapy]INFO:Enableditempipelines:
2014-08-2104:09:11+0800[scrapy]DEBUG:Telnetconsolelisteningon127.0.0.1:6024
2014-08-2104:09:11+0800[scrapy]DEBUG:Webservicelisteningon127.0.0.1:6081
2014-08-2104:09:11+0800[default]INFO:Spideropened
2014-08-2104:09:12+0800[default]DEBUG:Crawled(200)<GEThttp://www.baidu.com/>(referer:None)
[s]AvailableScrapyobjects:
[s]crawler<scrapy.crawler.Crawlerobjectat0xa483cec>
[s]item{}
[s]request<GEThttp://www.baidu.com/>
[s]response<200http://www.baidu.com/>
[s]settings<scrapy.settings.Settingsobjectat0xa0de78c>
[s]spider<Spider'default'at0xa78086c>
[s]Usefulshortcuts:
[s]shelp()Shellhelp(printthishelp)
[s]fetch(req_or_url)Fetchrequest(orURL)andupdatelocalobjects
[s]view(response)Viewresponseinabrowser
>>>
#response.body返回的所有内容
#response.xpath('//ul/li')可以测试所有的xpath内容
Moreimportant,ifyoutyperesponse.selectoryouwillaccessaselectorobjectyoucanuseto
querytheresponse,andconvenientshortcutslikeresponse.xpath()andresponse.css()mappingto
response.selector.xpath()andresponse.selector.css()
也就是可以很方便的,以交互的形式来查看xpath选择是否正确。之前是用FireFox的F12来选择的,但是并不能保证每次都能正确的选择出内容。
也可使用:
scrapyshell'http://scrapy.org'--nolog #参数--nolog没有日志
(2)示例
fromscrapyimportSpider
fromscrapy_test.itemsimportDmozItem
classDmozSpider(Spider):
name='dmoz'
allowed_domains=['dmoz.org']
start_urls=['http://www.dmoz.org/Computers/Programming/Languages/Python/Books/',
'http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/,'
'']
defparse(self,response):
forselinresponse.xpath('//ul/li'):
item=DmozItem()
item['title']=sel.xpath('a/text()').extract()
item['link']=sel.xpath('a/@href').extract()
item['desc']=sel.xpath('text()').extract()
yielditem
(3)保存文件
可以使用,保存文件。格式可以json,xml,csv
scrapycrawl-o'a.json'-t'json'
(4)使用模板创建spider
scrapygenspiderbaidubaidu.com #-*-coding:utf-8-*- importscrapy classBaiduSpider(scrapy.Spider): name="baidu" allowed_domains=["baidu.com"] start_urls=( 'http://www.baidu.com/', ) defparse(self,response): pass
这段先这样吧,记得之前5个的,现在只能想起4个来了.:-(
千万记得随手点下保存按钮。否则很是影响心情的(⊙o⊙)!
三、高级--scrapy.contrib.spiders.CrawlSpider
例子
#coding=utf-8
fromscrapy.contrib.spidersimportCrawlSpider,Rule
fromscrapy.contrib.linkextractorsimportLinkExtractor
importscrapy
classTestSpider(CrawlSpider):
name='test'
allowed_domains=['example.com']
start_urls=['http://www.example.com/']
rules=(
#元组
Rule(LinkExtractor(allow=('category\.php',),deny=('subsection\.php',))),
Rule(LinkExtractor(allow=('item\.php',)),callback='pars_item'),
)
defparse_item(self,response):
self.log('itempage:%s'%response.url)
item=scrapy.Item()
item['id']=response.xpath('//td[@id="item_id"]/text()').re('ID:(\d+)')
item['name']=response.xpath('//td[@id="item_name"]/text()').extract()
item['description']=response.xpath('//td[@id="item_description"]/text()').extract()
returnitem
其他的还有XMLFeedSpider
- classscrapy.contrib.spiders.XMLFeedSpider
- classscrapy.contrib.spiders.CSVFeedSpider
- classscrapy.contrib.spiders.SitemapSpider
四、选择器
>>>fromscrapy.selectorimportSelector >>>fromscrapy.httpimportHtmlResponse
可以灵活的使用.css()和.xpath()来快速的选取目标数据
关于选择器,需要好好研究一下。xpath()和css(),还要继续熟悉正则.
当通过class来进行选择的时候,尽量使用css()来选择,然后再用xpath()来选择元素的熟悉
五、ItemPipeline
Typicaluseforitempipelinesare:
•cleansingHTMLdata#清除HTML数据
•validatingscrapeddata(checkingthattheitemscontaincertainfields)#验证数据
•checkingforduplicates(anddroppingthem)#检查重复
•storingthescrapediteminadatabase#存入数据库
(1)验证数据
fromscrapy.exceptionsimportDropItem
classPricePipeline(object):
vat_factor=1.5
defprocess_item(self,item,spider):
ifitem['price']:
ifitem['price_excludes_vat']:
item['price']*=self.vat_factor
else:
raiseDropItem('Missingpricein%s'%item)
(2)写Json文件
importjson
classJsonWriterPipeline(object):
def__init__(self):
self.file=open('json.jl','wb')
defprocess_item(self,item,spider):
line=json.dumps(dict(item))+'\n'
self.file.write(line)
returnitem
(3)检查重复
fromscrapy.exceptionsimportDropItem
classDuplicates(object):
def__init__(self):
self.ids_seen=set()
defprocess_item(self,item,spider):
ifitem['id']inself.ids_seen:
raiseDropItem('Duplicateitemfound:%s'%item)
else:
self.ids_seen.add(item['id'])
returnitem
至于将数据写入数据库,应该也很简单。在process_item函数中,将item存入进去即可了。