scrapy基础 之 静态网页实例

1,scrapy爬虫基本流程:

    1. 创建一个新的Scrapy Project

    > scrapy startproject 项目名称    #系统会在当前目录下创建一个项目名称命名的文件夹,其下包含以下文件:

        scrapy.cfg: 项目配置文件

        items.py: 需要提取的数据结构定义文件,在items.py里面定义我们要抓取的数据:

        pipelines.py:管道定义,PipeLine用来对Spider返回的Item列表进行保存操作,可以写入到文件、或者数据库等。

        settings.py: 爬虫配置文件,包括发送请求次数,间隔时间,等等

        spiders: 放置spider的目录,也就是爬虫的主程序,至少包含以下三个要素:name:spider的标识,parse()方法:当start_urls里面的网页抓取下来之后需要调用这个方法解析网页内容,同时需要返回下一个需要抓取的网页,或者返回items列表。start_url :一个url列表,spider从这些网页开始抓取.

    2. 定义你需要从网页中提取的元素Item

    3.实现一个Spider类,通过接口完成爬取URL和提取Item的功能

    4. 实现一个Item PipeLine类,完成Item的存储功能

注意:

    > scrapy startproject huxiu2    #在当前文件夹创建一个名为huxiu2的文件夹,文件夹有settings,items,pipeline等文件构成一个爬虫框架

    自己写的爬虫程序要写在projectname/projectname/spiders目录下

2,配置items文件

目标:虎嗅网新闻列表的名称、链接地址和摘要爬取下来。

import scrapy
class HuxiuItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    title=scrapy.Field()
    link=scrapy.Field()
    desc=scrapy.Field()
    posttime=scrapy.Field()

注意:title,auther等内容将会是每行中存放信息的条目,也就是需要爬取的信息。

           输出和爬取程序不在一个文件里的好处是,未来可以使用Scrapy中其他有用的组件和帮助类。虽然目前感受不深,先按照框架来吧

3,写第一个spider

必不可少的要素:如果采用了items.py一定要先import一下,继承scrapy.Spider类并且有name,start_urls,parse。

from huxiu2.items import Huxiu2Item    #整个爬虫project的名字为huxiu2,
import scrapy

class Huxiu2Spider(scrapy.Spider):
    name = "huxi2"
    allowed_domains = ['huxiu.com']  # 只有这个域名下的子域名可以被允许爬取
    start_urls = ['http://www.huxiu.com/index.php']

    def parse(self, response):
        for sel in response.xpath('//div[@class ="mod-info-flow"]/div/div[@class="mob-ctt index-article-list-yh"]'):
            item = HuxiuItem()
            item['title'] = sel.xapth('h2/a/text()').extract_first()
            item['link'] = sel.xpath('h2/a/@href').extract_first()
            url = response.urljoin(item['link'])
            item['desc'] = sel.path('div[@class ="mob-sub"]/text()').extract_first()
            print item['title'],item['link'], item['desc']
#结果是无法爬取,估计需要设置headers。下文是修正版,啦啦啦,好from huxiu2.items import Huxiu2Item #整个爬虫project的名字为huxiimpofrom huxiu2.items import Huxiu2Item
import scrapy

class Huxiu2Spider(scrapy.Spider):
    name = "huxiu"
    # allowed_domains = ['huxiu.com']  # 只有这个域名下的子域名可以被允许爬取
    # start_urls = ['http://www.huxiu.com']    #有了重定义的start_requests就不用start_urls啦
    def start_requests(self):    
# start_urls作用是开始请求第一个网址,默认就是使用start_requests方法,不带任何参数地请求,现在我们为了爬取信息必须要带上参数,
# 所以我们要自定义一下这个方法。
# 下方的request默认参数是:url, callback=None, method='GET', headers=None, body=None,cookies=None, meta=None, encoding='utf-8',
# priority=0,dont_filter=False, errback=None, flags=None。 所以cookie和headers是分开的,至于其余的参数,以后详解
url='http://www.huxiu.com/index.php' head={ "User-Agent":"info" } cookie={'key':'value'} #自己去网页f12看哦,复制以后改成字典格式 yield scrapy.Request(url=url,cookies=cookie,callback=self.parse,headers=head) pass def parse(self, response): print ">>>>>呵呵" for i in response.xpath('//div[@class="mod-b mod-art clearfix "]'): item=Huxiu2Item() item['title'] = i.xpath('./div[@class="mob-ctt index-article-list-yh"]/h2/a/text()').extract_first() item['link']=i.xpath('./div[@class="mob-ctt index-article-list-yh"]/h2/a/@href').extract_first() item['desc']=i.xpath('.//div[@class="mob-sub"]/text()').extract_first() print item['title'],item['link'],item['desc']

 4,处理链接进入到每篇文章中获取信息

    在items.py文件中,我们定义了posttime=scrapy.Field(),但是发送时间只有在具体的文章被打开以后才能够得到,所以,我们要同时处理第二层网址。

from huxiu2.items import Huxiu2Item    #整个爬虫project的名字为huxiu2,
import scrapy

class Huxiu2Spider(scrapy.Spider):
    name = "huxi3"
    allowed_domains = ['huxiu.com']  # 只有这个域名下的子域名可以被允许爬取
    start_urls = ['http://www.huxiu.com']    #相当于第一次发出请求

    def parse(self, response):
        for sel in response.xpath('//div[@class ="mod-info-flow"]/div/div[@class="mob-ctt index-article-list-yh"]'):
            item = HuxiuItem()    #实例化一个item用于储存数据
            item['title'] = sel.xapth('h2/a/text()').extract_first()
            item['link'] = sel.xpath('h2/a/@href').extract_first()
            url = response.urljoin(item['link'])    #生成可访问的打开每一篇文章的新网址
            item['desc'] = sel.xpath('div[@class ="mob-sub"]/text()').extract_first()
            print item['title'],item['link'], item['desc']
            yield scrapy.Request(url,callback=self.parse_artical)    #开始第二层的请求,网址是url,callbac参数定义的是第二层爬取将调动哪个函数

    def parse_artical(self,response):
        item=Huxiu2Item()    #同样需要实例一下用来储存数据
        item['posttime']=response.xpath('//span[@class="article-time pull-left"]/text()').extract_first()
        item['link']=response.url    #进去第二层以后顺带更新一下litem['link'],因为之前的link不完整,不用之前的url变量是因为在此处更新可以确保新网址可打开。
        print item['posttime'],item['link']
        yield item

 5,导出抓取数据

第一种方法:直接打印:>scrapy crawl huxi3

第二种方法:导出结果到jason文件:>scrapy crawl huxiu -o items.json

第三种方法:保存到数据库

    保存到数据库,可以直接在spiders里面定义,也可以使用piplines

    直接写在spiders里面的方法:

from huxiu2.items import Huxiu2Item   #整个爬虫project的名字为huxiu2,
import scrapy,pymysql


class Huxiu2Spider(scrapy.Spider):
    name = "huxiu"
    def start_requests(self):
        url='http://www.huxiu.com/index.php'
        head={
            "User-Agent":"xxx"
        }
        cookie={
            "xxx": "yyy"
        }
        yield scrapy.Request(url=url,cookies=cookie,callback=self.parse,headers=head)
        pass

    def parse(self, response):
        db = pymysql.connect("localhost", "root", "xxxx", "xxxx")    #先要连接上数据库
        cursor = db.cursor()    
        sql="""create table huxiu(`title` varchar(50),`link` varchar(50),`desc` varchar(50))DEFAULT CHARSET=utf8"""    #设置数据表的编码方式
        try:
            cursor.execute(sql)    #创建数据表新表
            db.commit()
        except:
            db.rollback()
            print "error first try"
for i in response.xpath('//div[@class="mod-b mod-art clearfix "]'): item=Huxiu2Item() item['title'] = i.xpath('./div[@class="mob-ctt index-article-list-yh"]/h2/a/text()').extract_first().encode("utf-8") tmplink=i.xpath('./div[@class="mob-ctt index-article-list-yh"]/h2/a/@href').extract_first().encode("utf-8") item['link']=response.urljoin(tmplink).encode("utf-8") item['desc']=i.xpath('.//div[@class="mob-sub"]/text()').extract_first().encode("utf-8") #加encode的原因是原数据是unicode格式的 #print '第一层',item['title'],item['link'],item['desc'] a=str(item['title']) b=str(item['link']) c=str(item['desc']) print item['title'],"结果" sql2="""INSERT INTO huxiu VALUES ('%s', '%s','%s')""" % (a,b,c) #传参到sql语句中,%s表示传的是字符串 try: cursor.execute(sql2) db.commit() except: db.rollback() print "error of second try" db.close()

    使用pipeline的方法:

    注意:要想使用pipeline,

          首先得在spiders中有yield item作为结尾,只要这样才能生成item,否则item是空的;

               其次得在settings中启用pipelines,格式如下:ITEM_PIPELINES = {'huxiu2.pipelines.Huxiu2PipelinesJson': 300,},字典的键是自定义的pipeline函数名

               最后要注意pipeline内的class下的函数基本有三个,分别在开始中间和结束时候执行

spider的代码:

from huxiu2.items import Huxiu2Item   #整个爬虫project的名字为huxiu2,
import scrapy,pymysql

class Huxiu2Spider(scrapy.Spider):
    name = "huxiu"
    def start_requests(self):    #自定义的request方法
        url='http://www.huxiu.com/index.php'
        head={
            "User-Agent":"yyy"
        }
        cookie={
            "xxx": "yyy"
        }
        yield scrapy.Request(url=url,cookies=cookie,callback=self.parse,headers=head)
        pass

    def parse(self, response):    #自定义的信息获取函数
        for i in response.xpath('//div[@class="mod-b mod-art clearfix "]'):
            item=Huxiu2Item()
            item['title'] = i.xpath('./div[@class="mob-ctt index-article-list-yh"]/h2/a/text()').extract_first().encode("utf-8")
            tmplink=i.xpath('./div[@class="mob-ctt index-article-list-yh"]/h2/a/@href').extract_first().encode("utf-8")
            item['link']=response.urljoin(tmplink).encode("utf-8")
            item['desc']=i.xpath('.//div[@class="mob-sub"]/text()').extract_first().encode("utf-8")
            print '第一层',item['title'],item['link'],item['desc']    #为了看到是否可以成功爬取信息,为了搞明白pipelines的原理
            yield item    #yield item非常必要

pipelines的代码:

# -*- coding: utf-8 -*-

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html

import json

class Huxiu2PipelinesJson(object):
    def __init__(self):
        print '开始时候执行'    #在得到有用数据以前打印出来
        self.file=open('Huxiu.json','w')    #会在当前目录生成Huxiu.json文件

    def process_item(self, item, spider):
        print 'process_item running'    #每次print一组信息以后就会打印出这句话,说明item是一条一条写进json文件中的,而不是生成item以后再总的写进去
        content=json.dumps(dict(item),ensure_ascii=False)+'\n'    #python信息转化为json信息的函数
        self.file.write(content)
        return item

    def close_spider(self,spider):
        print '结束时候'    #有用的信息执行完毕后打印出来这句话
        self.file.close()

猜你喜欢

转载自www.cnblogs.com/0-lingdu/p/9532350.html