###运行spider,将爬取到的信息用JSON形式存到scraped_data.json文件中
scrapy crawl my_spider -o scraped_data.json
###在scrapy shell里面打印返回的html
response.body
###创建一个Spider,我们必须继承
scrapy.Spider
类(或者别的爬虫类),并且定义以下3个属性- name:用于区别Spider。 该名字必须是唯一的,您不可以为不同的Spider设定相同的名字。
- start_urls:包含了Spider在启动时进行爬取的url列表。 因此,第一个被获取到的页面将是其中之一(每个url都会被爬取)。
后续的URL则从初始的URL获取到的数据中提取
。 - parse() 是spider的一个方法。 被调用时,
每个初始URL完成下载后生成的 Response 对象将会作为唯一的参数传递给该函数
。 该方法负责解析返回的数据(response data),提取数据(生成item)以及生成需要进一步处理的URL的 Request 对象。parse只是初始url的回调函数,可以定义别的回调函数来处理后序的链接。
###scrapy shell
scrapy shell "http://www.dmoz.org/Computers/Programming/Languages/Python/Books/"
当您在终端运行Scrapy时,请一定记得给url地址加上
引号
,否则包含参数的url(例如 & 字符)会导致Scrapy运行失败。###Item 对象是自定义的python字典。 您可以使用标准的字典语法来获取到其每个字段的值。(字段即是我们之前用Field赋值的属性):
>>> item = DmozItem() >>> item['title'] = 'Example title' >>> item['title'] 'Example title'
###
scrapy.cfg
存放的目录被认为是 项目的根目录 。该文件中包含python模块名的字段定义了项目的设置Link Extractors 是用于从网页(scrapy.http.Response )中抽取会被follow的链接的对象。
scrapy.contrib.linkextractors import LinkExtractor
###log服务
Scrapy提供了log功能。您可以通过 scrapy.log 模块使用。当前底层实现使用了 Twisted logging ,不过可能在之后会有所变化。###使用FormRequest.from_response()方法模拟用户登录
通常网站通过 实现对某些表单字段(如数据或是登录界面中的认证令牌等)的预填充。 使用Scrapy抓取网页时,如果想要预填充或重写像用户名、用户密码这些表单字段, 可以使用 FormRequest.from_response() 方法实现。下面是使用这种方法的爬虫例子:import scrapy class LoginSpider(scrapy.Spider): name = 'example.com' start_urls = ['http://www.example.com/users/login.php'] def start_requests(self): return scrapy.FormRequest.from_response( "url", formdata={'username': 'john', 'password': 'secret'}, callback=self.after_login ) def after_login(self, response): # check login succeed before going on if "authentication failed" in response.body: self.log("Login failed", level=log.ERROR) return # continue scraping with authenticated session...
###Scrapy是以广度优先还是深度优先进行爬取的呢
默认情况下,Scrapy使用 LIFO 队列来存储等待的请求。简单的说,就是 深度优先顺序 。深度优先对大多数情况下是更方便的。如果您想以 广度优先顺序 进行爬取,你可以设置以下的设定:DEPTH_PRIORITY = 1 SCHEDULER_DISK_QUEUE = 'scrapy.squeue.PickleFifoDiskQueue' SCHEDULER_MEMORY_QUEUE = 'scrapy.squeue.FifoMemoryQueue'
###避免被禁止(ban)
有些网站实现了特定的机制,以一定规则来避免被爬虫爬取。 与这些规则打交道并不容易,需要技巧,有时候也需要些特别的基础。 如果有疑问请考虑联系 商业支持 。下面是些处理这些站点的建议(tips):
- 使用user agent池,轮流选择之一来作为user agent。池中包含常见的浏览器的user agent(google一下一大堆)
- 禁止cookies(参考 COOKIES_ENABLED),有些站点会使用cookies来发现爬虫的轨迹。
- 设置下载延迟(2或更高)。参考 DOWNLOAD_DELAY 设置。
- 如果可行,使用 Google cache 来爬取数据,而不是直接访问站点。
- 使用IP池。例如免费的 Tor项目 或付费服务(ProxyMesh)。
- 使用高度分布式的下载器(downloader)来绕过禁止(ban),您就只需要专注分析处理页面。这样的例子有: Crawlera
###禁止重试
对失败的HTTP请求进行重试会减慢爬取的效率,尤其是当站点响应很慢(甚至失败)时, 访问这样的站点会造成超时并重试多次。这是不必要的,同时也占用了爬虫爬取其他站点的能力。禁止重试:
RETRY_ENABLED = False
- ###使用相对Xpaths
如果你使用嵌套的选择器,并使用起始为 /
的XPath,那么该XPath将对文档使用绝对路径,而且对于你调用的 Selector 不是相对路径。
比如,假设你想提取在 <div>
元素中的所有 <p>
元素。首先,你将先得到所有的 <div>
元素:
>>> divs = response.xpath('//div')
开始时,你可能会尝试使用下面的错误的方法,因为它其实是从整篇文档中,而不仅仅是从那些 <div>
元素内部提取所有的 <p>
元素:
>>> for p in divs.xpath('//p'): # this is wrong - gets all <p> from the whole document
... print p.extract()
下面是比较合适的处理方法(注意 .//p XPath的点前缀):
>>> for p in divs.xpath('.//p'): # extracts all <p> inside
... print p.extract()
另一种常见的情况将是提取所有直系 <p>
的结果:
>>> for p in divs.xpath('p'):
... print p.extract()