美文网首页python爬虫
python爬虫--day07

python爬虫--day07

作者: 陈small末 | 来源:发表于2019-01-09 09:11 被阅读0次

    Scrapy Shell

    Scrapy终端是一个交互终端,我们可以在未启动spider的情况下尝试及调试代码

    启动Scrapy Shell

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" contenteditable="true" cid="n5" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">scrapy shell "https://hr.tencent.com/position.php?&start=0#a"</pre>

    Selectors选择器

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" contenteditable="true" cid="n7" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">Scrapy Selectors 内置 XPath 和 CSS Selector 表达式机制
    Selector有四个基本的方法,最常用的还是xpath:
    xpath(): 传入xpath表达式,返回该表达式所对应的所有节点的selector list列表
    extract(): 序列化该节点为Unicode字符串并返回list, extract_first()
    css(): 传入CSS表达式,返回该表达式所对应的所有节点的selector list列表,语法同 BeautifulSoup4
    re(): 根据传入的正则表达式对数据进行提取,返回Unicode字符串list列表

    使用xpath

    response.xpath('//title')</pre>

    Spider类

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" contenteditable="true" cid="n10" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">Spider类定义了如何爬取某个(或某些)网站。包括了爬取的动作(例如:是否跟进链接)以及如何从网页的内容中提取结构化数据(爬取item)。 换句话说,Spider就是你定义爬取的动作及分析某个网页(或者是有些网页)的地方。

    scrapy.Spider是最基本的类,所有编写的爬虫必须继承这个类。

    主要用到的函数及调用顺序为:
    init():
    初始化爬虫名字和start_urls列表
    start_requests()
    调用make_requests_from_url():生成Requests对象交给Scrapy下载并返回response
    parse():
    解析response,并返回Item或Requests(需指定回调函数)。
    Item传给Item pipline持久化,而Requests交由Scrapy下载,并由指定的回调函数处理(默认parse()),一直进行循环,直到处理完所有的数据为止。</pre>

    Spider类源码参考

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" contenteditable="true" cid="n12" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">#所有爬虫的基类,用户定义的爬虫必须从这个类继承
    class Spider(object_ref):

    定义spider名字的字符串(string)。

    spider的名字定义了Scrapy如何定位(并初始化)spider,所以其必须是唯一的。

    name是spider最重要的属性,而且是必须的。

    一般做法是以该网站(domain)(加或不加 后缀 )来命名spider。 例如,如果spider爬取 mywebsite.com ,该spider通常会被命名为 mywebsite

    name = None

    初始化,提取爬虫名字,start_urls

    def init(self, name=None, **kwargs):
    if name is not None:
    self.name = name

    如果爬虫没有名字,中断后续操作则报错

    elif not getattr(self, 'name', None):
    raise ValueError("%s must have a name" % type(self).name)

    python 对象或类型通过内置成员dict来存储成员信息

    self.dict.update(kwargs)

    URL列表。当没有指定的URL时,spider将从该列表中开始进行爬取。 因此,第一个被获取到的页面的URL将是该列表之一。 后续的URL将会从获取到的数据中提取。

    if not hasattr(self, 'start_urls'):
    self.start_urls = []

    打印Scrapy执行后的log信息

    def log(self, message, level=log.DEBUG, **kw):
    log.msg(message, spider=self, level=level, **kw)

    判断对象object的属性是否存在,不存在则断言处理

    def set_crawler(self, crawler):
    assert not hasattr(self, '_crawler'), "Spider already bounded to %s" % crawler
    self._crawler = crawler

    @property
    def crawler(self):
    assert hasattr(self, '_crawler'), "Spider not bounded to any crawler"
    return self._crawler

    @property
    def settings(self):
    return self.crawler.settings

    该方法将读取start_urls内的地址,并为每一个地址生成一个Request对象,交给Scrapy下载并返回Response

    该方法仅调用一次

    def start_requests(self):
    for url in self.start_urls:
    yield self.make_requests_from_url(url)

    start_requests()中调用,实际生成Request的函数。

    Request对象默认的回调函数为parse(),提交的方式为get

    def make_requests_from_url(self, url):
    return Request(url, dont_filter=True)

    默认的Request对象回调函数,处理返回的response。

    生成Item或者Request对象。用户必须实现这个

    def parse(self, response):
    raise NotImplementedError

    @classmethod
    def handles_request(cls, request):
    return url_is_from_spider(request.url, cls)

    def str(self):
    return "<%s %r at 0x%0x>" % (type(self).name, self.name, id(self))

    repr = str</pre>

    主要属性和方法
    • name

      定义spider名字的字符串。唯一

    • allowed_domains

      包含了spider允许爬取的域名(domain)的列表,可选。

    • start_urls

      初始URL元祖/列表。当没有制定特定的URL时,spider将从该列表中开始进行爬取。

    • start_requests(self)

      该方法必须返回一个可迭代对象(iterable)。该对象包含了spider用于爬取(默认实现是使用 start_urls 的url)的第一个Request。

      当spider启动爬取并且未指定start_urls时,该方法被调用。

    • parse(self, response)

      当请求url返回网页没有指定回调函数时,默认的Request对象回调函数。用来处理网页返回的response,以及生成Item或者Request对象。

    • log(self, message[, level, component])

      使用 scrapy.log.msg() 方法记录日志信息。

    CrawlSpider

    CrawlSpider是Spider的派生类,Spider类的设计原则是只爬取start_url列表中的网页,而CrawlSpider类定义了一些规则(rule)来提供跟进link的方便的机制,从爬取的网页中获取link并继续爬取的工作更适合。

    CrawlSpider类源码参考

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" contenteditable="true" cid="n45" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">class CrawlSpider(Spider):
    rules = ()
    def init(self, *a, *kw):
    super(CrawlSpider, self).init(
    a, **kw)
    self._compile_rules()

    首先调用parse()来处理start_urls中返回的response对象

    parse()则将这些response对象传递给了_parse_response()函数处理,并设置回调函数为parse_start_url()

    设置了跟进标志位True

    parse将返回item和跟进了的Request对象

    def parse(self, response):
    return self._parse_response(response, self.parse_start_url, cb_kwargs={}, follow=True)

    处理start_url中返回的response,需要重写

    def parse_start_url(self, response):
    return []

    def process_results(self, response, results):
    return results

    从response中抽取符合任一用户定义'规则'的链接,并构造成Resquest对象返回

    def _requests_to_follow(self, response):
    if not isinstance(response, HtmlResponse):
    return
    seen = set()

    抽取之内的所有链接,只要通过任意一个'规则',即表示合法

    for n, rule in enumerate(self._rules):
    links = [l for l in rule.link_extractor.extract_links(response) if l not in seen]

    使用用户指定的process_links处理每个连接

    if links and rule.process_links:
    links = rule.process_links(links)

    将链接加入seen集合,为每个链接生成Request对象,并设置回调函数为_repsonse_downloaded()

    for link in links:
    seen.add(link)

    构造Request对象,并将Rule规则中定义的回调函数作为这个Request对象的回调函数

    r = Request(url=link.url, callback=self._response_downloaded)
    r.meta.update(rule=n, link_text=link.text)

    对每个Request调用process_request()函数。该函数默认为indentify,即不做任何处理,直接返回该Request.

    yield rule.process_request(r)

    处理通过rule提取出的连接,并返回item以及request

    def _response_downloaded(self, response):
    rule = self._rules[response.meta['rule']]
    return self._parse_response(response, rule.callback, rule.cb_kwargs, rule.follow)

    解析response对象,会用callback解析处理他,并返回request或Item对象

    def _parse_response(self, response, callback, cb_kwargs, follow=True):

    首先判断是否设置了回调函数。(该回调函数可能是rule中的解析函数,也可能是 parse_start_url函数)

    如果设置了回调函数(parse_start_url()),那么首先用parse_start_url()处理response对象,

    然后再交给process_results处理。返回cb_res的一个列表

    if callback:

    如果是parse调用的,则会解析成Request对象

    如果是rule callback,则会解析成Item

    cb_res = callback(response, **cb_kwargs) or ()
    cb_res = self.process_results(response, cb_res)
    for requests_or_item in iterate_spider_output(cb_res):
    yield requests_or_item

    如果需要跟进,那么使用定义的Rule规则提取并返回这些Request对象

    if follow and self._follow_links:

    返回每个Request对象

    for request_or_item in self._requests_to_follow(response):
    yield request_or_item

    def _compile_rules(self):
    def get_method(method):
    if callable(method):
    return method
    elif isinstance(method, basestring):
    return getattr(self, method, None)

    self._rules = [copy.copy(r) for r in self.rules]
    for rule in self._rules:
    rule.callback = get_method(rule.callback)
    rule.process_links = get_method(rule.process_links)
    rule.process_request = get_method(rule.process_request)

    def set_crawler(self, crawler):
    super(CrawlSpider, self).set_crawler(crawler)
    self._follow_links = crawler.settings.getbool('CRAWLSPIDER_FOLLOW_LINKS', True)</pre>

    LinkExtractors

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" contenteditable="true" cid="n47" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">使用LinkExtractors 的目的: 提取链接。每个LinkExtractor有唯一的公共方法是 extract_links(),它接收一个 Response 对象,并返回一个 scrapy.link.Link 对象。
    scrapy.linkextractors.LinkExtractor(
    allow = (),
    deny = (),
    allow_domains = (),
    deny_domains = (),
    deny_extensions = None,
    restrict_xpaths = (),
    tags = ('a','area'),
    attrs = ('href'),
    canonicalize = True,
    unique = True,
    process_value = None
    )

    主要参数:
    allow:满足括号中“正则表达式”的值会被提取,如果为空,则全部匹配。
    deny:与这个正则表达式(或正则表达式列表)匹配的URL一定不提取。
    allow_domains:会被提取的链接的domains。
    deny_domains:一定不会被提取链接的domains。
    restrict_xpaths:使用xpath表达式,和allow共同作用过滤链接。
    ​</pre>

    rules

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" contenteditable="true" cid="n49" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">在rules中包含一个或多个Rule对象,每个Rule对爬取网站的动作定义了特定操作。如果多个rule匹配了相同的链接,则根据规则在本集合中被定义的顺序,第一个会被使用。

    scrapy.spiders.Rule(
    link_extractor,
    callback = None,
    cb_kwargs = None,
    follow = None,
    process_links = None,
    process_request = None
    )

    link_extractor:是一个Link Extractor对象,用于定义需要提取的链接。
    callback: 从link_extractor中每获取到链接时,参数所指定的值作为回调函数,该回调函数接受一个response作为其第一个参数。
    注意:当编写爬虫规则时,避免使用parse作为回调函数。由于CrawlSpider使用parse方法来实现其逻辑,如果覆盖了parse方法,crawlspider将会运行失败。
    follow:是一个布尔(boolean)值,指定了根据该规则从response提取的链接是否需要跟进。 如果callback为None,follow默认设置为True ,否则默认为False。
    process_links:指定该spider中哪个的函数将会被调用,从link_extractor中获取到链接列表时将会调用该函数。该方法主要用来过滤。
    process_request:指定该spider中哪个的函数将会被调用, 该规则提取到每个request时都会调用该函数。 (用来过滤request)
    ​</pre>

    robots协议

    Robots协议(也称为爬虫协议、机器人协议等)的全称是“网络爬虫排除标准”(Robots Exclusion Protocol),网站通过Robots协议告诉搜索引擎哪些页面可以抓取,哪些页面不能抓取。robots.txt文件是一个文本文件。当一个搜索蜘蛛访问一个站点时,它会首先检查该站点根目录下是否存在robots.txt,如果存在,搜索机器人就会按照该文件中的内容来确定访问的范围;如果该文件不存在,所有的搜索蜘蛛将能够访问网站上所有没有被口令保护的页面。

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" contenteditable="true" cid="n53" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">User-agent: * 这里的代表的所有的搜索引擎种类,是一个通配符
    Disallow: /admin/ 这里定义是禁止爬寻admin目录下面的目录
    Disallow: /require/ 这里定义是禁止爬寻require目录下面的目录
    Disallow: /ABC/ 这里定义是禁止爬寻ABC目录下面的目录
    Disallow: /cgi-bin/.htm 禁止访问/cgi-bin/目录下的所有以".htm"为后缀的URL(包含子目录)。
    Disallow: /
    ?* 禁止访问网站中所有包含问号 (?) 的网址
    Disallow: /.jpg禁止抓取网页所有的.jpg格式的图片 Disallow:/ab/adc.html 禁止爬取ab文件夹下面的adc.html文件。 Allow: /cgi-bin/ 这里定义是允许爬寻cgi-bin目录下面的目录 Allow: /tmp 这里定义是允许爬寻tmp的整个目录 Allow: .htm 仅允许访问以".htm"为后缀的URL。
    Allow: .gif$ 允许抓取网页和gif格式图片
    Sitemap: 网站地图 告诉爬虫这个页面是网站地图</pre>

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" contenteditable="true" cid="n54" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">实例分析:淘宝网的 robots.txt文件
    http://www.taobao.com/robots.txt</pre>

    禁止robots协议将 ROBOTSTXT_OBEY = True改为False

    Logging

    Scrapy提供了log功能,可以通过 logging 模块使用。

    可以修改配置文件settings.py,任意位置添加下面两行,效果会清爽很多。

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" contenteditable="true" cid="n61" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">LOG_ENABLED = True # 开启
    LOG_FILE = "TencentSpider.log" #日志文件名
    LOG_LEVEL = "INFO" #日志级别</pre>

    Log levels

    • Scrapy提供5层logging级别:

    • CRITICAL - 严重错误(critical)

    • ERROR - 一般错误(regular errors)

    • WARNING - 警告信息(warning messages)

    • INFO - 一般信息(informational messages)

    • DEBUG - 调试信息(debugging messages)

    logging设置

    通过在setting.py中进行以下设置可以被用来配置logging:

    LOG_ENABLED

    默认: True,启用logging

    LOG_ENCODING

    默认: 'utf-8',logging使用的编码

    LOG_FILE

    默认: None,在当前目录里创建logging输出文件的文件名

    LOG_LEVEL

    默认: 'DEBUG',log的最低级别

    scrapy的日志模块已经被scrapy弃用,也可以使用python自带日志模块

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" contenteditable="true" cid="n87" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">import logging

    LOG_FORMAT = "%(asctime)s - %(levelname)s - %(message)s" # 设置输出格式
    DATE_FORMAT = "%Y/%m/%d %H:%M:%S" # 设置时间格式
    logging.basicConfig(filename='sina.log', filemode='a+', format=LOG_FORMAT, datefmt=DATE_FORMAT)

    logging.warning('错误')</pre>

    settings.py 设置抓取间隔

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" contenteditable="true" cid="n89" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">DOWNLOAD_DELAY = 0.25 # 设置下载间隔为250ms</pre>

    练习:爬取糗事百科翻页爬取地址: https://www.qiushibaike.com/8hr/page/{}/
    练习:爬取腾讯招聘网,翻页获取岗位名称,时间,招聘人数,并存入数据库 https://hr.tencent.com/position.php?keywords=&lid=2218&tid=87&start=0#a

    Settings配置

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" contenteditable="true" cid="n95" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">Scrapy设置(settings)提供了定制Scrapy组件的方法。可以控制包括核心(core),插件(extension),pipeline及spider组件。</pre>

    BOT_NAME

    默认: 'scrapybot'

    Scrapy项目实现的bot的名字(也为项目名称)。 这将用来构造默认 User-Agent,同时也用来log。

    当您使用 startproject 命令创建项目时其也被自动赋值。

    CONCURRENT_ITEMS

    默认: 100

    Item Processor(即 Item Pipeline) 同时处理(每个response的)item的最大值。

    CONCURRENT_REQUESTS

    默认: 16

    Scrapy downloader 并发请求(concurrent requests)的最大值。

    CONCURRENT_REQUESTS_PER_DOMAIN

    默认: 8

    对单个网站进行并发请求的最大值。

    CONCURRENT_REQUESTS_PER_IP

    默认: 0

    对单个IP进行并发请求的最大值。如果非0,则忽略 CONCURRENT_REQUESTS_PER_DOMAIN 设定, 使用该设定。 也就是说,并发限制将针对IP,而不是网站。

    该设定也影响 DOWNLOAD_DELAY: 如果 CONCURRENT_REQUESTS_PER_IP 非0,下载延迟应用在IP而不是网站上。

    DEFAULT_REQUEST_HEADERS

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" contenteditable="true" cid="n114" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">DEFAULT_REQUEST_HEADERS = {
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8',
    'Accept-Language': 'en',
    }</pre>

    Scrapy HTTP Request使用的默认header。由 DefaultHeadersMiddleware 产生。

    DEPTH_LIMIT

    默认: 0

    爬取网站最大允许的深度(depth)值。如果为0,则没有限制。

    DEPTH_PRIORITY

    默认: 0

    整数值。用于根据深度调整request优先级。

    如果为0,则不根据深度进行优先级调整。

    DEPTH_STATS

    默认: True

    是否收集最大深度数据。

    DEPTH_STATS_VERBOSE

    默认: False

    是否收集详细的深度数据。如果启用,每个深度的请求数将会被收集在数据中。

    DNSCACHE_ENABLED

    默认: True

    是否启用DNS内存缓存(DNS in-memory cache)。

    DOWNLOADER

    默认: 'scrapy.core.downloader.Downloader'

    用于crawl的downloader.

    DOWNLOADER_MIDDLEWARES

    默认:: {}

    保存项目中启用的下载中间件及其顺序的字典。

    DOWNLOADER_MIDDLEWARES_BASE

    默认:

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" contenteditable="true" cid="n140" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">{
    'scrapy.contrib.downloadermiddleware.robotstxt.RobotsTxtMiddleware': 100,
    'scrapy.contrib.downloadermiddleware.httpauth.HttpAuthMiddleware': 300,
    'scrapy.contrib.downloadermiddleware.downloadtimeout.DownloadTimeoutMiddleware': 350,
    'scrapy.contrib.downloadermiddleware.useragent.UserAgentMiddleware': 400,
    'scrapy.contrib.downloadermiddleware.retry.RetryMiddleware': 500,
    'scrapy.contrib.downloadermiddleware.defaultheaders.DefaultHeadersMiddleware': 550,
    'scrapy.contrib.downloadermiddleware.redirect.MetaRefreshMiddleware': 580,
    'scrapy.contrib.downloadermiddleware.httpcompression.HttpCompressionMiddleware': 590,
    'scrapy.contrib.downloadermiddleware.redirect.RedirectMiddleware': 600,
    'scrapy.contrib.downloadermiddleware.cookies.CookiesMiddleware': 700,
    'scrapy.contrib.downloadermiddleware.httpproxy.HttpProxyMiddleware': 750,
    'scrapy.contrib.downloadermiddleware.chunked.ChunkedTransferMiddleware': 830,
    'scrapy.contrib.downloadermiddleware.stats.DownloaderStats': 850,
    'scrapy.contrib.downloadermiddleware.httpcache.HttpCacheMiddleware': 900,
    }
    ​</pre>

    包含Scrapy默认启用的下载中间件的字典。 永远不要在项目中修改该设定.

    DOWNLOADER_STATS

    默认: True

    是否收集下载器数据。

    DOWNLOAD_DELAY

    默认: 0

    下载器在下载同一个网站下一个页面前需要等待的时间。该选项可以用来限制爬取速度, 减轻服务器压力。同时也支持小数:

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" contenteditable="true" cid="n148" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">DOWNLOAD_DELAY = 0.25 # 250 ms of delay</pre>

    DOWNLOAD_TIMEOUT

    默认: 180

    下载器超时时间(单位: 秒)。

    EXTENSIONS

    默认:: {}

    保存项目中启用的插件及其顺序的字典。

    EXTENSIONS_BASE

    默认:

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" contenteditable="true" cid="n157" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">{
    'scrapy.contrib.corestats.CoreStats': 0,
    'scrapy.webservice.WebService': 0,
    'scrapy.telnet.TelnetConsole': 0,
    'scrapy.contrib.memusage.MemoryUsage': 0,
    'scrapy.contrib.memdebug.MemoryDebugger': 0,
    'scrapy.contrib.closespider.CloseSpider': 0,
    'scrapy.contrib.feedexport.FeedExporter': 0,
    'scrapy.contrib.logstats.LogStats': 0,
    'scrapy.contrib.spiderstate.SpiderState': 0,
    'scrapy.contrib.throttle.AutoThrottle': 0,
    }
    ​</pre>

    可用的插件列表。需要注意,有些插件需要通过设定来启用。默认情况下, 该设定包含所有稳定(stable)的内置插件。

    ITEM_PIPELINES

    默认: {}

    保存项目中启用的pipeline及其顺序的字典。该字典默认为空,值(value)任意。 不过值(value)习惯设定在0-1000范围内。

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" contenteditable="true" cid="n162" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">ITEM_PIPELINES = {
    'mybot.pipelines.validate.ValidateMyItem': 300,
    'mybot.pipelines.validate.StoreMyItem': 800,
    }
    ​</pre>

    ITEM_PIPELINES_BASE

    默认: {}

    保存项目中默认启用的pipeline的字典。 永远不要在项目中修改该设定,而是修改 ITEM_PIPELINES

    LOG_ENABLED

    默认: True

    是否启用logging。

    LOG_ENCODING

    默认: 'utf-8'

    logging使用的编码。

    LOG_FILE

    默认: None

    logging输出的文件名。如果为None,则使用标准错误输出(standard error)。

    LOG_LEVEL

    默认: 'DEBUG'

    log的最低级别。可选的级别有: CRITICAL、 ERROR、WARNING、INFO、DEBUG。更多内容请查看 Logging

    LOG_STDOUT

    默认: False

    如果为 True ,进程所有的标准输出(及错误)将会被重定向到log中。例如, 执行 print 'hello' ,其将会在Scrapy log中显示。

    MEMDEBUG_ENABLED

    默认: False

    是否启用内存调试(memory debugging)。

    MEMDEBUG_NOTIFY

    默认: []

    如果该设置不为空,当启用内存调试时将会发送一份内存报告到指定的地址;否则该报告将写到log中。

    样例:

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" contenteditable="true" cid="n190" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">MEMDEBUG_NOTIFY = ['user@example.com']</pre>

    MEMUSAGE_ENABLED

    默认: False

    Scope: scrapy.contrib.memusage

    是否启用内存使用插件。当Scrapy进程占用的内存超出限制时,该插件将会关闭Scrapy进程, 同时发送email进行通知。

    MEMUSAGE_LIMIT_MB

    默认: 0

    Scope: scrapy.contrib.memusage

    在关闭Scrapy之前所允许的最大内存数(单位: MB)(如果 MEMUSAGE_ENABLED为True)。 如果为0,将不做限制。

    MEMUSAGE_NOTIFY_MAIL

    默认: False

    Scope: scrapy.contrib.memusage

    达到内存限制时通知的email列表。

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" contenteditable="true" cid="n203" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">MEMUSAGE_NOTIFY_MAIL = ['user@example.com']</pre>

    MEMUSAGE_REPORT

    默认: False

    Scope: scrapy.contrib.memusage

    每个spider被关闭时是否发送内存使用报告。

    MEMUSAGE_WARNING_MB

    默认: 0

    Scope: scrapy.contrib.memusage

    在发送警告email前所允许的最大内存数(单位: MB)(如果 MEMUSAGE_ENABLED为True)。 如果为0,将不发送警告。

    NEWSPIDER_MODULE

    默认: ''

    使用 genspider 命令创建新spider的模块。

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" contenteditable="true" cid="n215" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">NEWSPIDER_MODULE = 'mybot.spiders_dev'</pre>

    REDIRECT_MAX_TIMES

    默认: 20

    定义request允许重定向的最大次数。超过该限制后该request直接返回获取到的结果。 对某些任务我们使用Firefox默认值。

    REDIRECT_PRIORITY_ADJUST

    默认: +2

    修改重定向请求相对于原始请求的优先级。

    ROBOTSTXT_OBEY

    默认: False

    Scope: scrapy.contrib.downloadermiddleware.robotstxt

    如果启用,Scrapy将会尊重 robots.txt策略。

    SCHEDULER

    默认: 'scrapy.core.scheduler.Scheduler'

    用于爬取的调度器。

    SPIDER_CONTRACTS

    默认:: {}

    保存项目中启用用于测试spider的scrapy contract及其顺序的字典

    SPIDER_CONTRACTS_BASE

    默认:

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" contenteditable="true" cid="n234" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">{
    'scrapy.contracts.default.UrlContract' : 1,
    'scrapy.contracts.default.ReturnsContract': 2,
    'scrapy.contracts.default.ScrapesContract': 3,
    }
    ​</pre>

    保存项目中默认启用的scrapy contract的字典。 永远不要在项目中修改该设定,而是修改SPIDER_CONTRACTS

    SPIDER_MIDDLEWARES

    默认:: {}

    保存项目中启用的下载中间件及其顺序的字典。

    SPIDER_MIDDLEWARES_BASE

    默认:

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" contenteditable="true" cid="n241" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">{
    'scrapy.contrib.spidermiddleware.httperror.HttpErrorMiddleware': 50,
    'scrapy.contrib.spidermiddleware.offsite.OffsiteMiddleware': 500,
    'scrapy.contrib.spidermiddleware.referer.RefererMiddleware': 700,
    'scrapy.contrib.spidermiddleware.urllength.UrlLengthMiddleware': 800,
    'scrapy.contrib.spidermiddleware.depth.DepthMiddleware': 900,
    }
    ​</pre>

    保存项目中默认启用的spider中间件的字典。 永远不要在项目中修改该设定,而是修改SPIDER_MIDDLEWARES

    SPIDER_MODULES

    默认: []

    Scrapy搜索spider的模块列表。

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" contenteditable="true" cid="n246" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">SPIDER_MODULES = ['mybot.spiders_prod', 'mybot.spiders_dev']</pre>

    STATS_CLASS

    默认: 'scrapy.statscol.MemoryStatsCollector'

    收集数据的类。该类必须实现 状态收集器(Stats Collector) API.

    STATS_DUMP

    默认: True

    当spider结束时dump Scrapy状态数据 (到Scrapy log中)。

    STATSMAILER_RCPTS

    默认: []

    spider完成爬取后发送Scrapy数据。

    TELNETCONSOLE_ENABLED

    默认: True

    表明 telnet 终端 (及其插件)是否启用的布尔值。

    TELNETCONSOLE_PORT

    默认: [6023, 6073]

    telnet终端使用的端口范围。如果设置为 None0 , 则使用动态分配的端口。

    TEMPLATES_DIR

    默认: scrapy模块内部的 templates

    使用 startproject 命令创建项目时查找模板的目录。

    URLLENGTH_LIMIT

    默认: 2083

    Scope: contrib.spidermiddleware.urllength

    爬取URL的最大长度。

    USER_AGENT

    默认: "Scrapy/VERSION (+http://scrapy.org)"

    爬取的默认User-Agent,除非被覆盖。

    REACTOR_THREADPOOL_MAXSIZE

    线程池数量,默认10条

    Scrapy反反爬策略

    通常反反爬主要有以下几个策略:

    设置User-Agent(随机切换User-Agent,模拟不同用户的浏览器信息)

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" contenteditable="true" cid="n278" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">添加请求头的多种方式

    方法1:

    修改setting.py中的User-Agent

    USER_AGENT = 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36'

    方法2:

    修改setting中的DEFAULT_REQUEST_HEADERS

    DEFAULT_REQUEST_HEADERS = {
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8',
    'Accept-Language': 'en',
    'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36'
    }

    方法3:

    在代码中修改。

    class HeadervalidationSpider(scrapy.Spider):
    name = 'headervalidation'
    allowed_domains = ['helloacm.com']

    重写start_requests

    def start_requests(self):
    header={'User-Agent':'ua'}
    yield scrapy.Request(url='', headers=header, callback=self.parse)

    def parse(self, response):
    pass</pre>

    禁用Cookies

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" contenteditable="true" cid="n280" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">也就是不启用cookies middleware,不向Server发送cookies,有些网站通过cookie的使用发现爬虫行为
    可以通过COOKIES_ENABLED控制 CookiesMiddleware 开启或关闭
    除非特殊需要,可以禁用cookies,防止某些网站根据Cookie来封锁爬虫。
    COOKIES_ENABLED = False</pre>

    设置延迟下载

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" contenteditable="true" cid="n282" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">防止访问过于频繁,设置为 2秒 或更高
    DOWNLOAD_DELAY = 3</pre>

    使用IP地址池

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" contenteditable="true" cid="n284" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">VPN和代理IP,现在大部分网站都反IP的</pre>

    自定义中间件

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" contenteditable="true" cid="n288" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">process_request(self, request, spider)
    当每个request通过下载中间件时,该方法被调用。

    process_response(self, request, response, spider)
    当下载器完成http请求,传递响应给引擎的时候调用</pre>

    修改settings.py配置USER_AGENTS和PROXIES

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" contenteditable="true" cid="n290" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"># 添加USER_AGENTS:
    USER_AGENTS = [
    "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 2.0.50727; Media Center PC 6.0)",
    "Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 1.0.3705; .NET CLR 1.1.4322)",
    "Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 3.0.04506.30)",
    "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN) AppleWebKit/523.15 (KHTML, like Gecko, Safari/419.3) Arora/0.3 (Change: 287 c9dfb30)",
    "Mozilla/5.0 (X11; U; Linux; en-US) AppleWebKit/527+ (KHTML, like Gecko, Safari/419.3) Arora/0.6",
    "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.2pre) Gecko/20070215 K-Ninja/2.1.1",
    "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9) Gecko/20080705 Firefox/3.0 Kapiko/3.0",
    "Mozilla/5.0 (X11; Linux i686; U;) Gecko/20070322 Kazehakase/0.4.5"
    ]

    添加代理IP设置PROXIES:

    免费代理IP可以网上搜索(免费的不太稳定),或者付费购买一批可用的私密代理IP:

    PROXIES = [
    {'ip_port': '111.8.60.9:8123'},
    {'ip_port': '101.71.27.120:80'},
    {'ip_port': '122.96.59.104:80'},
    {'ip_port': '122.224.249.122:8088'},
    ]</pre>

    创建中间件类

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" contenteditable="true" cid="n292" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"># -- coding: utf-8 --
    import random
    from settings import USER_AGENTS
    from settings import PROXIES

    随机的User-Agent

    class RandomUserAgent(object):
    def process_request(self, request, spider):
    useragent = random.choice(USER_AGENTS)
    request.headers.setdefault("User-Agent", useragent)

    随机代理IP

    class RandomProxy(object):
    def process_request(self, request, spider):
    proxy = random.choice(PROXIES)
    request.meta['proxy'] = "http://" + proxy['ip_port']</pre>

    配置中间件

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm" lang="python" contenteditable="true" cid="n294" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"># 最后设置setting.py里的DOWNLOADER_MIDDLEWARES,添加自己编写的下载中间件类
    DOWNLOADER_MIDDLEWARES = {

    'mySpider.middlewares.MyCustomDownloaderMiddleware': 543,

    'mySpider.middlewares.RandomUserAgent': 81,
    'mySpider.middlewares.ProxyMiddleware': 100
    }</pre>

    相关文章

      网友评论

        本文标题:python爬虫--day07

        本文链接:https://www.haomeiwen.com/subject/eqvprqtx.html