首先观察我们的spider:
class CnblogsSpider(scrapy.Spider):
name = 'cnblogs'
allowed_domains = ['news.cnblogs.com'] # 允许的域名
start_urls = ['http://news.cnblogs.com/'] # 起始url
def parse(self, response):
pass
它继承了scrapy.Spider,里面有很多默认的函数。
可以看到start_ulrs是一个list,里面可以放入我们需要爬取的所有url。在确定爬取策略时,有一个方案是拼凑出所有页面的url,此时,把它们放入到start_url中即可。
点进所继承的Spider,里面有一个函数:
def start_requests(self):
cls = self.__class__
if method_is_overridden(cls, Spider, 'make_requests_from_url'):
warnings.warn(
"Spider.make_requests_from_url method is deprecated; it "
"won't be called in future Scrapy releases. Please "
"override Spider.start_requests method instead (see %s.%s)." % (
cls.__module__, cls.__name__
),
)
for url in self.start_urls:
yield self.make_requests_from_url(url)
else:
for url in self.start_urls:
yield Request(url, dont_filter=True)
start_requests实际上是对start_urls进行了一个遍历,传给make_requests_from_url或Request,而实际上,make_requests_from_url实际上是直接return了一个Request:
def make_requests_from_url(self, url):
""" This method is deprecated. """
return Request(url, dont_filter=True)
Request会通过yeild命令直接交给scrapy的下载器,下载器会根据request下载所有东西,下载完成之后,会跑到cnblogs.py中的parse函数中进行调用的。
原理以后再讲,现在我们只需要知道,每一个url下载后的内容都会进入到parse函数,parse函数会接收一个response,这个response类似于django中的HttpResponse。
在parse函数的pass处打一个断点,调试一下看看。
如何调试呢?pycharm不提供scrapy模板,无法直接调试。我们可以写一个自己的main.py文件,通过这个main.py文件调用命令行,完成调试。
项目根目录下新建main.py:
from scrapy.cmdline import execute
import sys
import os
# os.path.abspath(__file__) 是当前文件路径:F:\Program Files\爬虫项目\new\Spider\main.py
# os.path.dirname(os.path.abspath(__file__)) 是当前文件所在文件夹的路径:F:\Program Files\爬虫项目\new\Spider
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
# 调用execute可以执行scrapy脚本
execute(["scrapy", "crawl", "cnblogs"])
实际上,命令行启动spider的命令为:
scrapy crawl cnblogs
你可以看出命令行启动中的命令与脚本启动的中向execute函数中传入的list之间的关系了。
在调试之前,将settings.py中的一个参数的值改为False:
# Obey robots.txt rules
ROBOTSTXT_OBEY = False
它的默认值是True,如果我们不改成False,spider会读取每一个网站上的robots协议,把不符合robots协议的url过滤掉。
debug我们刚刚编写的main.py脚本,发现成功运行到了parse函数中:
可以看到response的内容:
首先它是HtmlResponse类型,实际上scrapy有好几种Response,比如TextResponse。
url是所访问的网址。
status为200表示返回是正常的。
发现DEFAULT_ENCODING是ascii,但scrapy本身设置的是utf8。
body是整个源文件的内容,今后的操作实际上就是对这个body进行操作的。