作者:trinity Python 2016-7-25 标签: programming
当然是简单的爬虫,做这个工作最合适的是 Python 了。
1.给定初始地址,下载页面
2.从页面中解析出内容页面链接(列表A),解析出下一页链接(地址B)
3.循环下载列表A链接地址文件,解析出需要的条目(字典C)。保存(标注1)
4.地址B存在,下载地址B文件,跳转到步骤2
5.地址B不存在,结束。
(标注1:可以保存到文件,csv,各种(no)sql数据库,比较理想的是保存到 elasticsearch)
中间会涉及到 https,cookies,gzip,登录,验证码这些细节,碰到再说吧。找个简单的网站试试。www.coolshell.cn 这个博客不错。本来用 Requests 和 lxml 来完成大部分的工作,怎么架构,怎么定义接口,想想 Scrapy 应该会节约我不少时间,不是说好的“人生苦短,我用 Python”么。
pip install scrapy
不出意外,会碰到 lxml 的编译错误.安装依赖:
sudo apt install openssl sudo apt install libssl-dev sudo apt install python-openssl sudo apt install libxslt1-dev
命令行输入 scrapy 显示帮助。scrapy 是个蜘蛛框架,就像MFC之于Windows, .Net 之于 C#
cd myspiders scrapy startproject pin cd pin scrapy genspider pinruan coolshell.com
就产生了一只名为 pinruan 的爬虫,它怎么爬,还需要进一步指挥。以上几条命令类似于 VisualStudio 自动生成代码的 Wizard,生成了一批文件:
scrapy.cfg -- scrapy 在这个project的配置文件
pin/items.py -- 定义要抓取的数据条目,对应上文 字典C。
pin/pipelines.py -- 处理 字典C 的自定义方式
pin/settings.py -- 设置文件,关于这个爬虫所有要设置的条目
pin/spiders/pinruan.py -- 爬虫文件,怎么爬就在这里指挥
先来修改 items.py
import scrapy class BlogItem(scrapy.Item): # define the fields for your item here like: title = scrapy.Field() # 标题 content=scrapy.Field() # 内容 catalog=scrapy.Field() # 类别 tags =scrapy.Field() # time=scrapy.Field() # 日期 author=scrapy.Field()先简单着来,保存为 json 文件,修改 pipelines.py
import json import codecs class PinPipeline(object): def __init__(self): self.file=codecs.open('items.json','wb',encoding='utf-8') def process_item(self, item, spider): line=json.dumps(dict(item),ensure_ascii=False) + "\n" self.file.write(line) return item def close_spider(self,spider): self.file.close()注意,这里用 codecs 库来打开,在 json.dumps 中指定 ensure_ascii=False ,否则一般的 utf-8 编码的网页不能正常保存。
然后 settings.py 中启用 PinPipeline
ITEM_PIPELINES = { 'pin.pipelines.PinPipeline': 300, }到了指挥爬取的时候了,好在整个逻辑还是比较简单的。编辑 pinruan.py
import scrapy from scrapy.selector import HtmlXPathSelector from pin.items import BlogItem class PinruanSpider(scrapy.Spider): name = "pinruan" allowed_domains = ["coolshell.cn"] start_urls = ( 'http://coolshell.cn', ) def parse_content(self, response): blogs = response.xpath('//div[@class="post"]') for blog in blogs: item = BlogItem() item['title']=blog.xpath('h2/text()').extract_first() item['time']=blog.xpath('div/span[@class="date"]/text()').extract_first() item['author']=blog.xpath('div/span/a[@rel="author"]/text()').extract_first() item['content']=blog.xpath('div[@class="content"]/node()').extract() item['catalog']=blog.xpath('div/span/a[@rel="category tag"]/text()').extract() item['tags']=blog.xpath('div/span/a[@rel="tag"]/text()').extract() yield item def parse(self, response): #request blog content for url in response.xpath("//a[@class='title']"): post_url = url.xpath('@href').extract_first() #print post_url yield scrapy.Request(post_url,callback=self.parse_content) # request next page pages = response.xpath('//div[@class="wp-pagenavi"]/span[@class="current"]/following-sibling::*') if(len(pages) > 0): next_page_url = pages.xpath('@href').extract_first() yield scrapy.Request(next_page_url,callback=self.parse) print next_page_url回到命令行
cd ~/myspiders/pin scrapy crawl pinruan (--nolog)开始爬取。这个爬虫没有下载文章使用的图片,60多页的博客下载完毕还不到10M,博客空间要那么大干嘛?
备案号: 豫ICP备12008311号 Powered by Emlog Themed by SweetSlayer