本章学习爬虫的

  • 回调和跟踪链接
  • 使用参数

回调和跟踪链接

上一篇的另一个爬虫,这次是为了抓取作者信息

# -*- coding: utf-8 -*-
import scrapy class MyspiderAuthorSpider(scrapy.Spider):
name = 'myspider_author'
start_urls = ['http://quotes.toscrape.com/'] def parse(self, response):
# 链接到作者页面
for href in response.xpath('//div[@class="quote"]/span/a/@href'):
yield response.follow(href, self.parse_author) # 链接到下一页
for href in response.xpath('//li[@class="next"]/a/@href'):
yield response.follow(href, self.parse) def parse_author(self, response):
yield {
'name':response.xpath('//h3[@class="author-title"]/text()').extract_first(),
'birthdate':response.xpath('//span[@class="author-born-date"]/text()').extract_first()
}

这个爬虫将从主页面开始, 以 parse_author 回调方法跟踪所有到作者页面的链接,以 parse 回调方法跟踪其它页面。

这里我们将回调方法作为参数直接传递给 response.follow,这样代码更短,也可以传递给 scrapy.Request。

这个爬虫演示的另一个有趣的事是,即使同一作者有许多名言,我们也不用担心多次访问同一作者的页面。默认情况下,Scrapy 会将重复的请求过滤出来,避免了由于编程错误而导致的重复服务器的问题。如果你非要重复,改成这样:

yield response.follow(href, self.parse_author,dont_filter=True)

通过这样的爬虫,我们做了这样的一个事:获得了网站地图,挨着进去访问,获取信息.

上一篇最基础的爬虫,是根据"下一页",不停的往下找,中间可能会断掉,注意两者的区别

spider类参数传递

在运行爬虫时,可以通过 -a 选项为您的爬虫提供命令行参数:

dahu@dahu-OptiPlex-:~/PycharmProjects/SpiderLearning/quotesbot$ scrapy crawl toscrape-xpath-tag -a tag=humor -o t1.jl

默认情况下,这些参数将传递给 Spider 的 __init__ 方法并成为爬虫的属性。

在此示例中,通过 self.tag 获取命令行中参数 tag 的值。您可以根据命令行参数构建 URL,使您的爬虫只爬取特点标签的名言:

# -*- coding: utf-8 -*-
import scrapy class ToScrapeSpiderXPath(scrapy.Spider):
name = 'toscrape-xpath-tag'
start_urls = [
'http://quotes.toscrape.com/',
] def start_requests(self):
url = 'http://quotes.toscrape.com/'
tag = getattr(self, 'tag', None)
if tag is not None:
url = url + 'tag/' + tag
yield scrapy.Request(url, self.parse) def parse(self, response):
for quote in response.xpath('//div[@class="quote"]'):
yield {
'text': quote.xpath('./span[@class="text"]/text()').extract_first(),
'author': quote.xpath('.//small[@class="author"]/text()').extract_first(),
'tag': quote.xpath('.//div[@class="tags"]/a[@class="tag"]/text()').extract()
} next_page_url = response.xpath('//li[@class="next"]/a/@href').extract_first()
if next_page_url is not None:
yield scrapy.Request(response.urljoin(next_page_url))

当然你运行爬虫的时候,要是不加-a参数,也是可以正常运行的,这个方法是修改start_requests()方法

另个例子,直接修改__init__()方法

# -*- coding: utf-8 -*-
import scrapy class Dahu2Spider(scrapy.Spider):
name = 'dahu2'
allowed_domains = ['www.sina.com.cn']
start_urls = ['http://slide.news.sina.com.cn/s/slide_1_2841_197495.html'] def __init__(self,myurl=None,*args,**kwargs):
super(Dahu2Spider,self).__init__(*args,**kwargs)
if myurl==None:
myurl=Dahu2Spider.start_urls[0]
print("要爬取的网址为:%s"%myurl)
self.start_urls=["%s"%myurl] def parse(self, response):
yield {
'title':response.xpath('//title/text()').extract_first()
}
print response.xpath('//title/text()').extract_first()

运行:

dahu@dahu-OptiPlex-:~/PycharmProjects/SpiderLearning/quotesbot$ scrapy crawl dahu2 --nolog
要爬取的网址为:http://slide.news.sina.com.cn/s/slide_1_2841_197495.html
沈阳:男子养猪养出新花样 天天逼“二师兄”跳水锻炼_高清图集_新浪网
dahu@dahu-OptiPlex-:~/PycharmProjects/SpiderLearning/quotesbot$ scrapy crawl dahu2 -a myurl=http://www.sina.com.cn --nolog
要爬取的网址为:http://www.sina.com.cn
新浪首页

这里注意,yield方法,生成的是个字典的结构,我试了下别的,只能是这4个

-- :: [scrapy.core.scraper] ERROR: Spider must return Request, BaseItem, dict or None, got 'unicode' in <GET http://www.sina.com.cn>

当然我们这里用print打印出来显得很粗糙,用yield生成出来,就是这样子:

{'title': u'\u65b0\u6d6a\u9996\u9875'}

这里编码问题,可以通过json的库来解决,把内容输出到文件里,可以解决编码问题,这个就不细说了.

skill:

scrapy 在不同的抓取级别的Request之间传递参数的办法,下面的范例中,parse_item通过meat传递给了parse_details参数item,这样就可以再parse_details抓取完成所有的数据后一次返回

class MySpider(BaseSpider):
name = 'myspider'
start_urls = (
'http://example.com/page1',
'http://example.com/page2',
) def parse(self, response):
# collect `item_urls`
for item_url in item_urls:
yield Request(url=item_url, callback=self.parse_item) def parse_item(self, response):
item = MyItem()
# populate `item` fields
yield Request(url=item_details_url, meta={'item': item},
callback=self.parse_details) def parse_details(self, response):
item = response.meta['item']
# populate more `item` fields
return item

scrapy 学习笔记2的更多相关文章

  1. Scrapy:学习笔记(2)——Scrapy项目

    Scrapy:学习笔记(2)——Scrapy项目 1.创建项目 创建一个Scrapy项目,并将其命名为“demo” scrapy startproject demo cd demo 稍等片刻后,Scr ...

  2. Scrapy:学习笔记(1)——XPath

    Scrapy:学习笔记(1)——XPath 1.快速开始 XPath是一种可以快速在HTML文档中选择并抽取元素.属性和文本的方法. 在Chrome,打开开发者工具,可以使用$x工具函数来使用XPat ...

  3. scrapy 学习笔记1

    最近一段时间开始研究爬虫,后续陆续更新学习笔记 爬虫,说白了就是获取一个网页的html页面,然后从里面获取你想要的东西,复杂一点的还有: 反爬技术(人家网页不让你爬,爬虫对服务器负载很大) 爬虫框架( ...

  4. scrapy学习笔记(1)

    初探scrapy,发现很多入门教程对应的网址都失效或者改变布局了,走了很多弯路.于是自己摸索做一个笔记. 环境是win10 python3.6(anaconda). 安装 pip install sc ...

  5. Scrapy学习笔记(5)-CrawlSpider+sqlalchemy实战

    基础知识 class scrapy.spiders.CrawlSpider 这是抓取一般网页最常用的类,除了从Spider继承过来的属性外,其提供了一个新的属性rules,它提供了一种简单的机制,能够 ...

  6. scrapy学习笔记一

    以前写爬虫都是直接手写获取response然后用正则匹配,被大佬鄙视之后现在决定开始学习scrapy 一.安装 pip install scrapy 二.创建项目 scrapy startprojec ...

  7. Scrapy 学习笔记(一)数据提取

    Scrapy 中常用的数据提取方式有三种:Css 选择器.XPath.正则表达式. Css 选择器 Web 中的 Css 选择器,本来是用于实现在特定 DOM 元素上应用花括号内的样式这样一个功能的. ...

  8. scrapy 学习笔记

    1.scrapy 配合 selenium.phantomJS 抓取动态页面, 单纯的selemium 加 Firefox浏览器就可以抓取动态页面了, 但开启窗口太耗资源,而且一般服务器的linux 没 ...

  9. scrapy学习笔记

    1.scrapy用哪条命令行重新编辑已有的项目?cd projectname 2.如何在pycharm中开启scrapy?先在终端创建一个项目(即文件夹),再在pycharm中打开.

随机推荐

  1. Linux应用编程之串口操作20170901

    主要介绍在Linux应用程序下对串口的操作: 1.串口初始化 int InitCom() { int Ret; Ret = SerailComm.OpenCom( ComPortDevPath, 0 ...

  2. Codeforces 894.C Marco and GCD Sequence

    C. Marco and GCD Sequence time limit per test 1 second memory limit per test 256 megabytes input sta ...

  3. 洛谷P1078 文化之旅

    P1078 文化之旅 1.1K通过 3.6K提交 题目提供者洛谷OnlineJudge 标签NOIp普及组2012 难度普及+/提高 时空限制1s / 128MB 提交  讨论  题解 最新讨论更多讨 ...

  4. Codeforces 833B The Bakery dp线段树

    B. The Bakery time limit per test 2.5 seconds memory limit per test 256 megabytes input standard inp ...

  5. Qt ------ 控件布局 setSizePolicy

    setSizePolicy 是设置控件在布局(layout)里面的大小变化的属性.如果控件没有在布局里,没什么用. 默认情况下,把 widget 放入 layout,widget 的大小一定程度上会随 ...

  6. 「Django」rest_framework学习系列-版本认证

    1.自己写: class UserView(APIView): versioning_class = ParamVersion def get(self,request,*args,**kwargs) ...

  7. at org.codehaus.jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:142) :json转化“$ref 循环引用”的问题

    原因: entity实体中存在@OneToMany,@ManyToOne注解,在转化json是产生了循环引用 报的错误 解决方法: springmvc @ResponseBody 默认的json转化用 ...

  8. 使用git拉取github上的项目

    一. 安装Git 去Git官网,下载安装包,一路点next,默认安装. 安装之后,在空白处右键,菜单显示有 Git GUI Here 和 Git Bash Here ,表示Git安装成功. 二. 配置 ...

  9. HDU 5145 分块 莫队

    给定n个数,q个询问[l,r]区间,每次询问该区间的全排列多少种. 数值都是30000规模 首先考虑计算全排列,由于有同种元素存在,相当于每次在len=r-l+1长度的空格随意放入某种元素即$\bin ...

  10. 理解 CSS 中的伪元素 :before 和 :after

    CSS 的主要目的是给 HTML 元素添加样式,然而,在一些案例中给文档添加额外的元素是多余的或是不可能的.事实上 CSS 中有一个特性允许我们添加额外元素而不扰乱文档本身,这就是“伪元素”. 你一定 ...