scrapy 爬虫框架记要

scrapy 就是一个帮助爬取网站数据,帮助提取网站结构化数据的框架。

 

组件概览:

 

Scheduler  :  

Scrapy Engine:  引擎负责数据流在整个系统中的流动,也就是在你start 启动的那一瞬间,会有相应触发事件。 

spiders:  爬虫程序, 里包括如何爬取网页,分析返回的response,提取item或者继续进入下一个URL,每一个spider都负责处理一个或者一些网站。

Downloader:负责获取页面数据并提供给引擎,然后提供给spider

∆∆Item Pipeline: 持久化(存取数据到数据库或者文件中), item Pipeline 负责处理被spiders爬取到的item(也就是html元素) ,将元素放入到这根管道中,管道中可以使用一些信号自定义一些操作。

Downloader Middlewares: 就是一个勾子,可以扩展scrapy功能。ø

Spider Middlewares: 也是一个勾子,可以扩展。

 

使用:

启动一个爬虫:

scrapy startproject  projectName
cd projectName
scrapy gendspider baidu  www.baidu.com #生成一个要爬取baidu网页的爬虫, 这里可以生成多个爬虫 。
scrapy crawl speedycloud --nolog. 启动爬虫,不显示日志

注解:

settings.py 文件 :

ROBOTSTXT_OBEY = False
# Obey robots.txt rules #机器人协议,当蜘蛛在爬取一个网站时,首先会访问网站的robots.txt这个协议
# ,如同酒店里的"请匆打扰"挂牌,这个规则如同你尊重不尊重网站提供者的意愿

案例:

伯乐在线 的每篇文章点操作:

案例地址:git@github.com:tonywyl/jobbole_spider.git

# -*- coding: utf-8 -*-
import scrapy
import requests
import re
from scrapy.selector import Selector
from scrapy.http import HtmlResponse,Request

class XiaohuaSpider(scrapy.Spider):
    name = 'xiaohua'
    allowed_domains = ['jobbole.com']
    start_urls = ['http://www.jobbole.com/']
    cookie_dict={}
    def start_requests(self):
        for url in self.start_urls:
            yield Request(url,dont_filter=True,callback=self.parse0)

    def parse0(self,response):

        """
        登录
        :param response:
        :return:
        """

        login_url='http://www.jobbole.com/wp-admin/admin-ajax.php'

        post_data={
            "action": "user_login",
            "user_login": 'beijinessa',
            "user_pass": 'seBBub%5w*Xa95gc',
            "remember_me": 1,
            "redirect_url": "http://www.jobbole.com",
        }
        import urllib.parse

        yield Request(url=login_url,
                      method='POST',
                      body=urllib.parse.urlencode(post_data),
                      headers={'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8'},
                      callback=self.parse,
                      )
        print('登录操作:写入日志')

    def parse(self, response):
        print('login')
        """
        进入首页
        :param response:
        :return:
        """
        # print(response.text)
        # result=Selector(text=response.text).xpath('//h3/text()').extract()#不加extract 是保留HTML标签
        # print(response.text,'----')



        yield Request(url='http://www.jobbole.com/',callback=self.parse00)


        """
        android---- http://android.jobbole.com/wp-admin/admin-ajax.php
        top:        http://top.jobbole.com/wp-admin/admin-ajax.php
        http://group.jobbole.com/wp-admin/admin-ajax.php

        点赞
        formdata
        {
        action:vote_post_action
        post_id:93250
        }
        """


    def parse00(self,response):
        """
        跳转至这一篇文章
        :param response:
        :return:
        """
        # print(response.text,'=-=-=-')

        url_list = response.selector.xpath('//div[@class="post-meta"]/p/a[@class="meta-title"]/@href').extract()
        # print(url_list)
        for url in url_list:
            yield Request(url=url, method='GET', callback=self.parse1)


    def parse1(self,response):

        last_url=re.findall('http://\w+\.\w+\.com',response.url)[0]#http://blog.jobbole.com/112239
        last_url=last_url+'/wp-admin/admin-ajax.php'
        hxs=Selector(response)
        id=hxs.xpath('//div[@class="post-adds"]/span/@data-post-id').extract_first()
        # print(id,'=======')
        """cookie 获取"""
        from scrapy.http.cookies import CookieJar
        cookie_jar = CookieJar()
        cookie_jar.extract_cookies(response, response.request)

        for k, v in cookie_jar._cookies.items():
            for i, j in v.items():
                for m, n in j.items():
                    self.cookie_dict[m] = n.value

        data={
          "action":"vote_post_action",
          "post_id":id,

      }
        # print(last_url)
        import urllib.parse
        # print(id, '---#--------')
        yield Request(url=last_url,
                      method='POST',
                      body=urllib.parse.urlencode(data),
                      headers={"Content-Type":"application/x-www-form-urlencoded; charset=UTF-8"},
                      callback=self.parse2)

    def parse2(self,response):
        # print(response.text)

        from ..items import TutorialItem
        yield TutorialItem(text=response.text) #注册使用持久化。
        # print(response.text,'---',)
        # print(response.encoding('utf-8'),'---',)

持久化:items.py  #因为在parse2 函数注册了持久化,便会将text 进入pipeline 

import scrapy


class TutorialItem(scrapy.Item):
    # define the fields for your item here like:
    text = scrapy.Field()
    # pass

而pipeline 则可以做一些自己想要做的操作:如将item 写入日志

class TutorialPipeline(object):
    def __init__(self):
        self.f=None
    def process_item(self, item, spider):
     #在spider/jobble.py的parse2 函数中,只要一yield就会触发process_item
print('process item',item) self.f.write(item) return item @classmethod def from_crawler(cls, crawler):      #只要爬虫一 start ,这个函数便会被触发,如果没有__init__的话。 print('pipline from process',) return cls() def open_spider(self,spider): #这是一个信号,当爬虫一打开就会触发这个,其余的还有close_spider self.f = open('log.log', 'ab+') print('spider start crawle write databases')

 

posted @ 2017-09-02 16:47  tonycloud  阅读(254)  评论(0)    收藏  举报