关键字:scrapy 入门教程 爬虫 Spider
作者:http://www.cnblogs.com/txw1958/
出处:http://www.cnblogs.com/txw1958/archive/2012/07/16/scrapy-tutorial.html

在这篇入门教程中,我们假定你已经安装了Scrapy。如果你还没有安装,那么请参考安装指南

我们将使用开放目录项目(dmoz)作为抓取的例子。

这篇入门教程将引导你完成如下任务:

  1. 创建一个新的Scrapy项目
  2. 定义提取的Item
  3. 写一个Spider用来爬行站点,并提取Items
  4. 写一个Item Pipeline用来存储提取出的Items

Scrapy是由Python编写的。如果你是Python新手,你也许希望从了解Python开始,以期最好的使用Scrapy。如果你对其它编程语言熟悉,想快速的学习Python,这里推荐 Dive Into Python。如果你对编程是新手,且想从Python开始学习编程,请看下面的对非程序员的Python资源列表

新建工程

在抓取之前,你需要新建一个Scrapy工程。进入一个你想用来保存代码的目录,然后执行:

  1. Microsoft Windows XP [Version 5.1.2600]
  2. (C) Copyright 1985-2001 Microsoft Corp.
  3.  
  4. T:\>scrapy startproject tutorial
  5. T:\>

这个命令会在当前目录下创建一个新目录tutorial,它的结构如下:

  1. T:\tutorial>tree /f
  2. Folder PATH listing
  3. Volume serial number is 0006EFCF C86A:7C52
  4. T:.
  5. scrapy.cfg

  6. └─tutorial
  7. items.py
  8. pipelines.py
  9. settings.py
  10. __init__.py

  11. └─spiders
  12. __init__.py

这些文件主要是:

  • scrapy.cfg: 项目配置文件
  • tutorial/: 项目python模块, 呆会代码将从这里导入
  • tutorial/items.py: 项目items文件
  • tutorial/pipelines.py: 项目管道文件
  • tutorial/settings.py: 项目配置文件
  • tutorial/spiders: 放置spider的目录

定义Item

Items是将要装载抓取的数据的容器,它工作方式像python里面的字典,但它提供更多的保护,比如对未定义的字段填充以防止拼写错误。

它通过创建一个scrapy.item.Item类来声明,定义它的属性为scrpy.item.Field对象,就像是一个对象关系映射(ORM). 
我们通过将需要的item模型化,来控制从dmoz.org获得的站点数据,比如我们要获得站点的名字,url和网站描述,我们定义这三种属性的域。要做到这点,我们编辑在tutorial目录下的items.py文件,我们的Item类将会是这样

  1. from scrapy.item import Item, Field
  2. class DmozItem(Item):
  3. title = Field()
  4. link = Field()
  5.     desc = Field()

刚开始看起来可能会有些困惑,但是定义这些item能让你用其他Scrapy组件的时候知道你的 items到底是什么。

我们的第一个爬虫(Spider)

Spider是用户编写的类,用于从一个域(或域组)中抓取信息。

他们定义了用于下载的URL的初步列表,如何跟踪链接,以及如何来解析这些网页的内容用于提取items。

要建立一个Spider,你必须为scrapy.spider.BaseSpider创建一个子类,并确定三个主要的、强制的属性:

  • name:爬虫的识别名,它必须是唯一的,在不同的爬虫中你必须定义不同的名字.
  • start_urls:爬虫开始爬的一个URL列表。爬虫从这里开始抓取数据,所以,第一次下载的数据将会从这些URLS开始。其他子URL将会从这些起始URL中继承性生成。
  • parse():爬虫的方法,调用时候传入从每一个URL传回的Response对象作为参数,response将会是parse方法的唯一的一个参数,

这个方法负责解析返回的数据、匹配抓取的数据(解析为item)并跟踪更多的URL。

这是我们的第一只爬虫的代码,将其命名为dmoz_spider.py并保存在tutorial\spiders目录下。

  1. from scrapy.spider import BaseSpider
  2.  
  3. class DmozSpider(BaseSpider):
  4. name = "dmoz"
  5. allowed_domains = ["dmoz.org"]
  6. start_urls = [
  7. "http://www.dmoz.org/Computers/Programming/Languages/Python/Books/",
  8. "http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/"
  9. ]
  10.  
  11. def parse(self, response):
  12. filename = response.url.split("/")[-2]
  13. open(filename, 'wb').write(response.body)

爬爬爬

为了让我们的爬虫工作,我们返回项目主目录执行以下命令

  1. T:\tutorial>scrapy crawl dmoz

crawl dmoz 命令从dmoz.org域启动爬虫。 你将会获得如下类似输出

  1. T:\tutorial>scrapy crawl dmoz
  2. 2012-07-13 19:14:45+0800 [scrapy] INFO: Scrapy 0.14.4 started (bot: tutorial)
  3. 2012-07-13 19:14:45+0800 [scrapy] DEBUG: Enabled extensions: LogStats, TelnetConsole, CloseSpider, WebService, CoreStats, SpiderState
  4. 2012-07-13 19:14:45+0800 [scrapy] DEBUG: Enabled downloader middlewares: HttpAuthMiddleware, DownloadTimeoutMiddleware, UserAgentMiddleware, RetryMiddleware, DefaultHeadersMiddleware, RedirectMiddleware, CookiesMiddleware, HttpCompressionMiddleware, ChunkedTransferMiddleware, DownloaderStats
  5. 2012-07-13 19:14:45+0800 [scrapy] DEBUG: Enabled spider middlewares: HttpErrorMiddleware, OffsiteMiddleware, RefererMiddleware, UrlLengthMiddleware, DepthMiddleware
  6. 2012-07-13 19:14:45+0800 [scrapy] DEBUG: Enabled item pipelines:
  7. 2012-07-13 19:14:45+0800 [dmoz] INFO: Spider opened
  8. 2012-07-13 19:14:45+0800 [dmoz] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min)
  9. 2012-07-13 19:14:45+0800 [scrapy] DEBUG: Telnet console listening on 0.0.0.0:6023
  10. 2012-07-13 19:14:45+0800 [scrapy] DEBUG: Web service listening on 0.0.0.0:6080
  11. 2012-07-13 19:14:46+0800 [dmoz] DEBUG: Crawled (200) <GET http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/> (referer: None)
  12. 2012-07-13 19:14:46+0800 [dmoz] DEBUG: Crawled (200) <GET http://www.dmoz.org/Computers/Programming/Languages/Python/Books/> (referer: None)
  13. 2012-07-13 19:14:46+0800 [dmoz] INFO: Closing spider (finished)
  14. 2012-07-13 19:14:46+0800 [dmoz] INFO: Dumping spider stats:
  15. {'downloader/request_bytes': 486,
  16. 'downloader/request_count': 2,
  17. 'downloader/request_method_count/GET': 2,
  18. 'downloader/response_bytes': 13063,
  19. 'downloader/response_count': 2,
  20. 'downloader/response_status_count/200': 2,
  21. 'finish_reason': 'finished',
  22. 'finish_time': datetime.datetime(2012, 7, 13, 11, 14, 46, 703000),
  23. 'scheduler/memory_enqueued': 2,
  24. 'start_time': datetime.datetime(2012, 7, 13, 11, 14, 45, 500000)}
  25. 2012-07-13 19:14:46+0800 [dmoz] INFO: Spider closed (finished)
  26. 2012-07-13 19:14:46+0800 [scrapy] INFO: Dumping global stats:
  27. {}

注意包含 [dmoz]的行 ,那对应着我们的爬虫。你可以看到start_urls中定义的每个URL都有日志行。因为这些URL是起始页面,所以他们没有引用(referrers),所以在每行的末尾你会看到 (referer: <None>). 
有趣的是,在我们的 parse  方法的作用下,两个文件被创建:分别是 Books 和 Resources,这两个文件中有URL的页面内容。

发生了什么事情?

Scrapy为爬虫的 start_urls属性中的每个URL创建了一个 scrapy.http.Request 对象 ,并将爬虫的parse 方法指定为回调函数。 
这些 Request首先被调度,然后被执行,之后通过parse()方法,scrapy.http.Response 对象被返回,结果也被反馈给爬虫。

提取Item

选择器介绍

我们有很多方法从网站中提取数据。Scrapy 使用一种叫做 XPath selectors的机制,它基于 XPath表达式。如果你想了解更多selectors和其他机制你可以查阅资料http://doc.scrapy.org/topics/selectors.html#topics-selectors 
这是一些XPath表达式的例子和他们的含义

  • /html/head/title: 选择HTML文档<head>元素下面的<title> 标签。
  • /html/head/title/text(): 选择前面提到的<title> 元素下面的文本内容
  • //td: 选择所有 <td> 元素
  • //div[@class="mine"]: 选择所有包含 class="mine" 属性的div 标签元素

这只是几个使用XPath的简单例子,但是实际上XPath非常强大。如果你想了解更多XPATH的内容,我们向你推荐这个XPath教程http://www.w3schools.com/XPath/default.asp

为了方便使用XPaths,Scrapy提供XPathSelector 类, 有两种口味可以选择, HtmlXPathSelector (HTML数据解析) 和XmlXPathSelector (XML数据解析)。 为了使用他们你必须通过一个 Response 对象对他们进行实例化操作。你会发现Selector对象展示了文档的节点结构。因此,第一个实例化的selector必与根节点或者是整个目录有关 。 
Selectors 有三种方法

  • select():返回selectors列表, 每一个select表示一个xpath参数表达式选择的节点.
  • extract():返回一个unicode字符串,该字符串为XPath选择器返回的数据
  • re(): 返回unicode字符串列表,字符串作为参数由正则表达式提取出来

尝试在shell中使用Selectors

为了演示Selectors的用法,我们将用到 内建的Scrapy shell,这需要系统已经安装IPython (一个扩展python交互环境) 。

附IPython下载地址:http://pypi.python.org/pypi/ipython#downloads

要开始shell,首先进入项目顶层目录,然后输入

  1. T:\tutorial>scrapy shell http://www.dmoz.org/Computers/Programming/Languages/Python/Books/

输出结果类似这样:

  1. 2012-07-16 10:58:13+0800 [scrapy] INFO: Scrapy 0.14.4 started (bot: tutorial)
  2. 2012-07-16 10:58:13+0800 [scrapy] DEBUG: Enabled extensions: TelnetConsole, CloseSpider, WebService, CoreStats, SpiderState
  3. 2012-07-16 10:58:13+0800 [scrapy] DEBUG: Enabled downloader middlewares: HttpAuthMiddleware, DownloadTimeoutMiddleware, UserAgentMiddleware, RetryMiddleware, DefaultHeadersMiddleware, RedirectMiddleware, CookiesMiddleware, HttpCompressionMiddleware, ChunkedTransferMiddleware, DownloaderStats
  4. 2012-07-16 10:58:13+0800 [scrapy] DEBUG: Enabled spider middlewares: HttpErrorMiddleware, OffsiteMiddleware, RefererMiddleware, UrlLengthMiddleware, DepthMiddleware
  5. 2012-07-16 10:58:13+0800 [scrapy] DEBUG: Enabled item pipelines:
  6. 2012-07-16 10:58:13+0800 [scrapy] DEBUG: Telnet console listening on 0.0.0.0:6023
  7. 2012-07-16 10:58:13+0800 [scrapy] DEBUG: Web service listening on 0.0.0.0:6080
  8. 2012-07-16 10:58:13+0800 [dmoz] INFO: Spider opened
  9. 2012-07-16 10:58:18+0800 [dmoz] DEBUG: Crawled (200) <GET http://www.dmoz.org/Computers/Programming/Languages/Python/Books/> (referer: None)
  10. [s] Available Scrapy objects:
  11. [s] hxs <HtmlXPathSelector xpath=None data=u'<html><head><meta http-equiv="Content-Ty'>
  12. [s] item {}
  13. [s] request <GET http://www.dmoz.org/Computers/Programming/Languages/Python/Books/>
  14. [s] response <200 http://www.dmoz.org/Computers/Programming/Languages/Python/Books/>
  15. [s] settings <CrawlerSettings module=<module 'tutorial.settings' from 'T:\tutorial\tutorial\settings.pyc'>>
  16. [s] spider <DmozSpider 'dmoz' at 0x1f68230>
  17. [s] Useful shortcuts:
  18. [s] shelp() Shell help (print this help)
  19. [s] fetch(req_or_url) Fetch request (or URL) and update local objects
  20. [s] view(response) View response in a browser
  21. WARNING: Readline services not available or not loaded.WARNING: Proper color support under MS Windows requires the pyreadline library.
  22. You can find it at:
  23. http://ipython.org/pyreadline.html
  24. Gary's readline needs the ctypes module, from:
  25. http://starship.python.net/crew/theller/ctypes
  26. (Note that ctypes is already part of Python versions 2.5 and newer).
  27.  
  28. Defaulting color scheme to 'NoColor'Python 2.7.3 (default, Apr 10 2012, 23:31:26) [MSC v.1500 32 bit (Intel)]
  29. Type "copyright", "credits" or "license" for more information.
  30.  
  31. IPython 0.13 -- An enhanced Interactive Python.
  32. ? -> Introduction and overview of IPython's features.
  33. %quickref -> Quick reference.
  34. help -> Python's own help system.
  35. object? -> Details about 'object', use 'object??' for extra details.
  36.  
  37. In [1]:

Shell载入后,你将获得回应,这些内容被存储在本地变量 response 中,所以如果你输入response.body 你将会看到response的body部分,或者输入response.headers 来查看它的 header部分。 
Shell也实例化了两种selectors,一个是解析HTML的  hxs 变量,一个是解析 XML 的 xxs 变量。我们来看看里面有什么:

  1. In [1]: hxs.select('//title')
  2. Out[1]: [<HtmlXPathSelector xpath='//title' data=u'<title>Open Directory - Computers: Progr'>]
  3.  
  4. In [2]: hxs.select('//title').extract()
  5. Out[2]: [u'<title>Open Directory - Computers: Programming: Languages: Python: Books</title>']
  6.  
  7. In [3]: hxs.select('//title/text()')
  8. Out[3]: [<HtmlXPathSelector xpath='//title/text()' data=u'Open Directory - Computers: Programming:'>]
  9.  
  10. In [4]: hxs.select('//title/text()').extract()
  11. Out[4]: [u'Open Directory - Computers: Programming: Languages: Python: Books']
  12.  
  13. In [5]: hxs.select('//title/text()').re('(\w+):')
  14. Out[5]: [u'Computers', u'Programming', u'Languages', u'Python']
  15.  
  16. In [6]:

提取数据

现在我们尝试从网页中提取数据。 
你可以在控制台输入 response.body, 检查源代码中的 XPaths 是否与预期相同。然而,检查HTML源代码是件很枯燥的事情。为了使事情变得简单,我们使用Firefox的扩展插件Firebug。更多信息请查看Using Firebug for scraping Using Firefox for scraping.
txw1958注:事实上我用的是Google Chrome的Inspect Element功能,而且可以提取元素的XPath。
检查源代码后,你会发现我们需要的数据在一个 <ul>元素中,而且是第二个<ul>。 
我们可以通过如下命令选择每个在网站中的 <li> 元素:

  1. hxs.select('//ul/li')

然后是网站描述:

  1. hxs.select('//ul/li/text()').extract()

网站标题:

  1. hxs.select('//ul/li/a/text()').extract()

网站链接:

  1. hxs.select('//ul/li/a/@href').extract()

如前所述,每个select()调用返回一个selectors列表,所以我们可以结合select()去挖掘更深的节点。我们将会用到这些特性,所以:

  1. sites = hxs.select('//ul/li')
  2. for site in sites:
  3. title = site.select('a/text()').extract()
  4. link = site.select('a/@href').extract()
  5. desc = site.select('text()').extract()
  6. print title, link, desc

Note 
更多关于嵌套选择器的内容,请阅读Nesting selectors 和 Working with relative XPaths

将代码添加到爬虫中:

txw1958注:代码有修改,绿色注释掉的代码为原教程的,你懂的

  1. from scrapy.spider import BaseSpider
  2. from scrapy.selector import HtmlXPathSelector
  3.  
  4. class DmozSpider(BaseSpider):
  5. name = "dmoz"
  6. allowed_domains = ["dmoz.org"]
  7. start_urls = [
  8. "http://www.dmoz.org/Computers/Programming/Languages/Python/Books/",
  9. "http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/"
  10. ]
  11.  
  12. def parse(self, response):
  13. hxs = HtmlXPathSelector(response)
  14. sites = hxs.select('//fieldset/ul/li')
  15. #sites = hxs.select('//ul/li')
  16. for site in sites:
  17. title = site.select('a/text()').extract()
  18. link = site.select('a/@href').extract()
  19. desc = site.select('text()').extract()
  20. #print title, link, desc
  21. print title, link

现在我们再次抓取dmoz.org,你将看到站点在输出中被打印 ,运行命令

  1. T:\tutorial>scrapy crawl dmoz

使用条目(Item)

Item 对象是自定义的python字典,使用标准字典类似的语法,你可以获取某个字段(即之前定义的类的属性)的值:

  1. >>> item = DmozItem()
  2. >>> item['title'] = 'Example title'
  3. >>> item['title']
  4. 'Example title'

Spiders希望将其抓取的数据存放到Item对象中。为了返回我们抓取数据,spider的最终代码应当是这样:

  1. from scrapy.spider import BaseSpider
  2. from scrapy.selector import HtmlXPathSelector
  3.  
  4. from tutorial.items import DmozItem
  5.  
  6. class DmozSpider(BaseSpider):
  7. name = "dmoz"
  8. allowed_domains = ["dmoz.org"]
  9. start_urls = [
  10. "http://www.dmoz.org/Computers/Programming/Languages/Python/Books/",
  11. "http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/"
  12. ]
  13.  
  14. def parse(self, response):
  15. hxs = HtmlXPathSelector(response)
  16. sites = hxs.select('//fieldset/ul/li')
  17. #sites = hxs.select('//ul/li')
  18. items = []
  19. for site in sites:
  20. item = DmozItem()
  21. item['title'] = site.select('a/text()').extract()
  22. item['link'] = site.select('a/@href').extract()
  23. item['desc'] = site.select('text()').extract()
  24. items.append(item)
  25. return items

现在我们再次抓取 :

  1. 2012-07-16 14:52:36+0800 [dmoz] DEBUG: Scraped from <200 http://www.dmoz.org/Computers/Programming/Languages/Python/Books/>
  2. {'desc': [u'\n\t\t\t\n\t',
  3. u' \n\t\t\t\n\t\t\t\t\t\n - Free Python books and tutorials.\n \n'],
  4. 'link': [u'http://www.techbooksforfree.com/perlpython.shtml'],
  5. 'title': [u'Free Python books']}
  6. 2012-07-16 14:52:36+0800 [dmoz] DEBUG: Scraped from <200 http://www.dmoz.org/Computers/Programming/Languages/Python/Books/>
  7. {'desc': [u'\n\t\t\t\n\t',
  8. u' \n\t\t\t\n\t\t\t\t\t\n - Annotated list of free online books on Python scripting language. Topics range from beginner to advanced.\n \n
  9. '],
  10. 'link': [u'http://www.freetechbooks.com/python-f6.html'],
  11. 'title': [u'FreeTechBooks: Python Scripting Language']}
  12. 2012-07-16 14:52:36+0800 [dmoz] DEBUG: Crawled (200) <GET http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/> (referer: None)
  13. 2012-07-16 14:52:36+0800 [dmoz] DEBUG: Scraped from <200 http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/>
  14. {'desc': [u'\n\t\t\t\n\t',
  15. u' \n\t\t\t\n\t\t\t\t\t\n - A directory of free Python and Zope hosting providers, with reviews and ratings.\n \n'],
  16. 'link': [u'http://www.oinko.net/freepython/'],
  17. 'title': [u'Free Python and Zope Hosting Directory']}
  18. 2012-07-16 14:52:36+0800 [dmoz] DEBUG: Scraped from <200 http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/>
  19. {'desc': [u'\n\t\t\t\n\t',
  20. u' \n\t\t\t\n\t\t\t\t\t\n - Features Python books, resources, news and articles.\n \n'],
  21. 'link': [u'http://oreilly.com/python/'],
  22. 'title': [u"O'Reilly Python Center"]}
  23. 2012-07-16 14:52:36+0800 [dmoz] DEBUG: Scraped from <200 http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/>
  24. {'desc': [u'\n\t\t\t\n\t',
  25. u' \n\t\t\t\n\t\t\t\t\t\n - Resources for reporting bugs, accessing the Python source tree with CVS and taking part in the development of Python.\n\n'],
  26. 'link': [u'http://www.python.org/dev/'],
  27. 'title': [u"Python Developer's Guide"]}

保存抓取的数据

保存信息的最简单的方法是通过Feed exports,命令如下:

  1. T:\tutorial>scrapy crawl dmoz -o items.json -t json

所有抓取的items将以JSON格式被保存在新生成的items.json 文件中

在像本教程一样的小型项目中,这些已经足够。然而,如果你想用抓取的items做更复杂的事情,你可以写一个 Item Pipeline(条目管道)。因为在项目创建的时候,一个专门用于条目管道的占位符文件已经随着items一起被建立,目录在tutorial/pipelines.py。如果你只需要存取这些抓取后的items的话,就不需要去实现任何的条目管道。

结束语

本教程简要介绍了Scrapy的使用,但是许多其他特性并没有提及。

对于基本概念的了解,请访问Basic concepts

我们推荐你继续学习Scrapy项目的例子dirbot,你将从中受益更深,该项目包含本教程中提到的dmoz爬虫。

Dirbot项目位于https://github.com/scrapy/dirbot

项目包含一个README文件,它详细描述了项目的内容。

如果你熟悉git,你可以checkout它的源代码。或者你可以通过点击Downloads下载tarball或zip格式的文件。

另外这有一个代码片断共享网站,里面共享内容包括爬虫,中间件,扩展应用,脚本等。网站名字叫Scrapy snippets,有好的代码要记得共享哦:-)

本教程的源代码下载:http://files.cnblogs.com/txw1958/scrapy_tutorial.rar

Scrapy入门教程(转)的更多相关文章

  1. [转]Scrapy入门教程

    关键字:scrapy 入门教程 爬虫 Spider 作者:http://www.cnblogs.com/txw1958/ 出处:http://www.cnblogs.com/txw1958/archi ...

  2. Scrapy入门教程

    关键字:scrapy 入门教程 爬虫 Spider作者:http://www.cnblogs.com/txw1958/出处:http://www.cnblogs.com/txw1958/archive ...

  3. 2019-03-22 Python Scrapy 入门教程 笔记

    Python Scrapy 入门教程 入门教程笔记: # 创建mySpider scrapy startproject mySpider # 创建itcast.py cd C:\Users\theDa ...

  4. python之scrapy入门教程

    看这篇文章的人,我假设你们都已经学会了python(派森),然后下面的知识都是python的扩展(框架). 在这篇入门教程中,我们假定你已经安装了Scrapy.如果你还没有安装,那么请参考安装指南. ...

  5. Scrapy 入门教程

    Scrapy 是用 Python 实现的一个为了爬取网站数据.提取结构性数据而编写的应用框架. Scrapy 常应用在包括数据挖掘,信息处理或存储历史数据等一系列的程序中. 通常我们可以很简单的通过 ...

  6. 一、Scrapy入门教程

    本文转载自以下链接:https://scrapy-chs.readthedocs.io/zh_CN/latest/intro/tutorial.html 在本篇教程中,我们假定您已经安装好Scrapy ...

  7. 【Python3爬虫】Scrapy入门教程

    Python版本:3.5            系统:Windows 一.准备工作 需要先安装几个库(pip,lxml,pywin32,Twisted,pyOpenSSL),这些都比较容易,如果使用的 ...

  8. 使用scrapy入门教程

    创建项目 scrapy startprogect demo 创建爬虫 scrapy genspider myDomain madomian.com 直接创建文件也可以 运行爬虫 scrapy craw ...

  9. 转:Scrapy安装、爬虫入门教程、爬虫实例(豆瓣电影爬虫)

    Scrapy在window上的安装教程见下面的链接:Scrapy安装教程 上述安装教程已实践,可行.(本来打算在ubuntu上安装Scrapy的,但是Ubuntu 磁盘空间太少了,还没扩展磁盘空间,所 ...

随机推荐

  1. UVALive 5760 Alice and Bob

    题意是黑板上有n个数\(S_i\).每次操作可以把其中一个数减1或者将两个数合并为一个数.一个数变为0时,则不能再对其操作. 思路是发现最大的可操作次数为\( \sum S_i\)+(n - 1).\ ...

  2. php返回json数据函数实例_php技巧_脚本之家

    本文实例讲述了php返回json数据函数的用法,分享给大家供大家参考.具体方法如下: json_encode()函数用法: echo json_encode(array('a'=>'bbbb', ...

  3. laravel 上传文件到亚马逊 aws s3

    参考: https://github.com/aws/aws-sdk-php-laravel https://www.jianshu.com/p/e48d82bff20b

  4. java版云笔记(七)之事务管理

    事务管理 事务:程序为了保证业务处理的完整性,执行的一条或多条SQL语句. 事务管理:对事务中的SQL语句进行提交或者回滚. 事物管理对于企业应用来说是至关重要的,好使出现异常情况,它也可以保证数据的 ...

  5. mysql 操作时间戳

    1.将long显示成时间 SELECT FROM_UNIXTIME(1249488000, '%Y%m%d' ) 2.日期格式化成时间戳 SELECT UNIX_TIMESTAMP('2016-05- ...

  6. CentOS 7.1使用yum安装MySql5.6.24

    http://www.cnblogs.com/yuanfeiblog/p/5276492.html

  7. 画弧线DrawArc的研究-我自己 -- 直线交接圆角

    procedure TForm4.Button7Click(Sender: TObject); var pwith: Integer; //画笔的宽度 hx1, hy1: Integer; //横线第 ...

  8. webpack编译时No PostCSS Config的解决方法

    1. { loader:"postcss-loader", options: { // 如果没有options这个选项将会报错 No PostCSS Config found pl ...

  9. day2 字符串常用方法总结

    字符串在Python中是常用的功能,我们知道,字符串在Python中存储的形式是以字符数组的形式存在,比如"alex"在内存中的存储形式是:["a"," ...

  10. Codeforces Round #302 (Div. 1) B - Destroying Roads

    B - Destroying Roads 思路:这么菜的题我居然想了40分钟... n^2枚举两个交汇点,点与点之间肯定都跑最短路,取最小值. #include<bits/stdc++.h> ...