scrapy基础复习(一)

正文:

原作者文章:https://www.cnblogs.com/cq146637/category/1218489.html
这一系列文章适合有一定scrapy基础的同学学习,个人感觉是一个较简单能稍微上手的小复习吧

#coding=utf-8
from scrapy.cmdline import execute
import sys
import os
a=sys.path.append(os.path.dirname(os.path.abspath(__file__)))
print os.path.abspath(__file__)
print os.path.dirname(os.path.abspath(__file__))
Scrapy内置settings
  • 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_ITEM_CLASS
    默认: ‘scrapy.item.Item’
    the Scrapy shell 中实例化item使用的默认类。
  • DEFAULT_REQUEST_HEADERS
    默认:

    {
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
        'Accept-Language': 'en',
    }

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

  • DOWNLOADER
    默认: ‘scrapy.core.downloader.Downloader’
    用于crawl的downloader.
  • DOWNLOADER_MIDDLEWARES
    默认:: {}
    保存项目中启用的下载中间件及其顺序的字典。
  • DOWNLOAD_DELAY
    默认: 0
    下载器在下载同一个网站下一个页面前需要等待的时间。该选项可以用来限制爬取速度, 减轻服务器压力。同时也支持小数:
  • DOWNLOAD_HANDLERS
    默认: {}
    保存项目中启用的下载处理器(request downloader handler)的字典。
  • DOWNLOAD_TIMEOUT
    默认: 180
    下载器超时时间(单位: 秒)。
  • EXTENSIONS
    默认:{}
    保存项目中启用的插件及其顺序的字典。
  • ITEM_PIPELINES
    默认: {}
    保存项目中启用的pipeline及其顺序的字典。该字典默认为空,值(value)任意。 不过值(value)习惯设定在0-1000范围内。
  • ITEM_PIPELINES_BASE
    默认: {}
    保存项目中默认启用的pipeline的字典。 永远不要在项目中修改该设定,而是修改 ITEM_PIPELINES 。
  • LOG_ENABLED
    默认: True
    是否启用logging。
  • LOG_ENCODING
    默认: ‘utf-8’
    logging使用的编码。
  • LOG_FILE
    默认: None
    logging输出的文件名。如果为None,则使用标准错误输出(standard error)。
  • LOG_FORMAT
    默认: ‘%(asctime)s [%(name)s] %(levelname)s: %(message)s’
    日志的数据格式
  • LOG_DATEFORMAT
    默认: ‘%Y-%m-%d %H:%M:%S’
    日志的日期格式
  • LOG_LEVEL
    默认: ‘DEBUG’
    log的最低级别。可选的级别有: CRITICAL、 ERROR、WARNING、INFO、DEBUG。
  • LOG_STDOUT
    默认: False
    如果为 True ,进程所有的标准输出(及错误)将会被重定向到log中。
  • RANDOMIZE_DOWNLOAD_DELAY
    默认: True
    如果启用,当从相同的网站获取数据时,Scrapy将会等待一个随机的值 (0.5到1.5之间的一个随机值 * DOWNLOAD_DELAY)。
    该随机值降低了crawler被检测到(接着被block)的机会。某些网站会分析请求, 查找请求之间时间的相似性。
  • REDIRECT_MAX_TIMES
    默认: 20
    定义request允许重定向的最大次数。超过该限制后该request直接返回获取到的结果。 对某些任务我们使用Firefox默认值。
  • ROBOTSTXT_OBEY
    默认: False
    是否遵循robots协议
  • SCHEDULER
    默认: ‘scrapy.core.scheduler.Scheduler’
    用于爬取的调度器。
  • SPIDER_MIDDLEWARES
    默认: {}
    保存项目中启用的下载中间件及其顺序的字典。
  • USER_AGENT
    默认: “Scrapy/VERSION (+http://scrapy.org)”
    爬取的默认User-Agent,除非被覆盖。

二.
xpath

body # 选取所有body元素的所有子节点
/html # 选取根元素
body/a # 选取所有属于body的子元素的a元素
//div # 选取所有dic子元素(任意地方)
body//div # 选取所有属于body元素的后代的div元素(body下任意位置)
//@class # 选取所有名为class的属性
/body/div[1] # 选取属于body子元素的第一个div元素
/body/div[last()] # 选取属于body子元素的最后一个div元素
//div[@lang] # 选取所有拥有lang属性的div元素
//div[@lang='eng'] # 选取所有lang属性为eng的div元素
/div/* # 获取属于div元素的所有子节点
//* # 选取所有元素
//div[@*] # 获取所有带属性的div元素
/div/a|//div/p # 获取所有div的子元素a和p
//span|ul # 选取文档中的span和ul元素
body/div/p|//span # 选取所有body下的div下的p元素和所有span元素
//span[contains(@class, 'vote-post-up')] # 寻找所有属性为class的值中包含vote-post-up的span标签

css

*   # 选择所有节点
#container  # 选择id为container的节点
.container  # 选取所有class包含container的节点
.container.hearder  # 选取所有class同时包含container和hearder的节点
li a    # 选取所有li下的所有a节点
ul + p  # 选择ul后面的第一个p元素
div#container > ul # 选取id为container的div的第一个ul子元素
ul ~ p # 选取与ul相邻的所有p元素
a[title]    # 选取所有title属性的a元素
a[href="http://www.baidu.com"]  # 选取所有href属性为http://www.baidu.com的a元素
a[href*="baidu"]    # 选取href属性包含baidu的a元素
a[href^="http"]     # 选取href属性以http开头的a元素
a[href$=".html"]     # 选取href属性以html结尾的a元素
input[type=radio]:checked   # 选取选中的radio的元素
div:not(#container) # 选取所有id非container的div属性
li:nth-child(3)     # 选取第三个li元素
tr:nth-child(2n)    # 选取偶数位tr元素

三.
回掉

        yield Request(url=parse.urljoin(response.url, url), meta={}, callback=self.parse)
def parse_detail(self, response):
    front_data = response.meta.get('xxx', '')
    pass

 
四.
下载图片的setting配置

ITEM_PIPELINES = {
    'ArticleSpider.pipelines.ArticlespiderPipeline': 300,
    'scrapy.pipelines.images.ArticleImagePipeline': 1,
}
IMAGES_URLS_FIELD = 'front_image_url'
import os
PROJECT_DIR = os.path.abspath(os.path.dirname(__file__))
IMAGES_STORE = os.path.join(PROJECT_DIR, 'images')
# 过滤图片大小
IMAGES_MIN_HEIGHT = 100
IMAGES_MIN_WIDTH = 100
# 自定制一个pipelines
# 添加一个class
from scrapy.pipelines.images import ImagesPipeline
class ArticleImagePipeline(ImagesPipeline):
    def item_completed(self, results, item, info):
        for res, value in results:
            image_path = value['path']
            item['front_image_path'] = image_path
        # 处理完成路径需要将item返回,因为在settings中,配置的了优先级,该pipelines可以将items继续传递给下一个pipelines中
        return item

五.json模块

class JsonwithEncodingPipeline(object):
    def __init__(self):
        self.file = codecs.open('article.json', 'w', encoding='utf-8')
    def process_item(self, item, spider):
        lines = json.dumps(dict(item), ensure_ascii=False) + '\n'
        self.file.write(lines)
        return item
    def spider_closed(self, spider):
        self.file.close()

内置JSON处理对象JsonItemExporter的使用

class JsonExporterPipeline(object):
    def __init__(self):
        self.file = open('articleexport.json', 'wb')
        self.exporter = JsonItemExporter(self.file, encoding='utf-8', ensure_ascii=False)
        self.exporter.start_exporting()
    def spider_closed(self, spider):
        self.exporter.finish_exporting()
        self.file.close()
    def process_item(self, item, spider):
        self.exporter.export_item(item)
        return item

六.数据库的写入
阻塞型的数据写入操作

class MysqlPipeline(object):
    def __init__(self):
        self.conn = pymysql.connect('192.168.1.1', 'root', '123456', 'titlespider',
                                    charset='utf-8', use_unicode=True)
        self.cursor = self.conn.cursor()
    def process_item(self, item, spider):
        insert_sql = """
            insert into article(title, cteate_time, url, content)
            VALUES (%s, %s, %s, %s)
        """
        self.cursor.execute(insert_sql, (item['title'], item['cteate_time'], item['url'], item['content']))
        self.conn.commit()
        return item

使用twisted提供的数据库连接池,异步化写入,缓解写数据操作堵塞

# 首先在settings定义数据库关键字变量
    MYSQL_HOST = '192.168.1.1'
    MYSQL_USER = 'root'
    MYSQL_PASSWD = '123456'
    MYSQL_DB = 'articlespider'
# 然后编写Pipeline类
    from twisted.enterprise import adbapi
    import pymysql
    import pymysql.cursors
    class MysqlTwistedPipeline(object):
        def __init__(self, dbpool):
            self.dbpool = dbpool
        @classmethod
        def from_settings(cls, settings):
            conn_dict = dict(
                host = settings['MYSQL_HOST'],
                user = settings['MYSQL_USER'],
                passwd = settings['MYSQL_PASSWD'],
                database = settings['MYSQL_DB'],
                charset = 'utf-8',
                cursorclass = pymysql.cursors.DictCursor,
                use_unicode = True
            )
            dbpool = adbapi.ConnectionPool('PyMySQL', **conn_dict)
            return cls(dbpool)
        def process_item(self, item, spider):
            query = self.dbpool.runInteraction(self.do_insert, item)
            query.addErrorback(self.handle_error)
            return item
        def do_insert(self, item):
            insert_sql = """
                        insert into article(title, cteate_time, url, content)
                        VALUES (%s, %s, %s, %s)
                    """
            self.cursor.execute(insert_sql, (item['title'], item['cteate_time'], item['url'], item['content']))
            self.conn.commit()
        def handle_error(self, failure):
            print(failure)
使用类似django-model的方式写入数据库
https://github.com/scrapy-plugins/scrapy-djangoitem

接下来的直接嵌入代码效果更好
Scrapy学习-8-ItemLoader
Scrapy学习-9-FromRequest
Scrapy学习-10-Request&Response对象
Scrapy学习-11-Selector对象使用
Scrapy学习-12-使用DownloaderMiddleware随机修改User-Agent
Scrapy学习-13-使用DownloaderMiddleware设置IP代理池及IP变换
Scrapy学习-14-验证码识别   (自己写的效果不好,网上的收费)
Scrapy学习-15-降低被识别为爬虫的方法
Scrapy学习-16-动态网页技术
Scrapy学习-17-暂停和重启
Scrapy学习-18-去重
Scrapy学习-19-远程管理telnet功能  (标记,还未测试)
Scrapy学习-20-数据收集
Scrapy学习-21-信号量   (标记)
Scrapy学习-23-分布式爬虫
Scrapy学习-24-集成elasticsearch  (标记)
Scrapy学习-25-Scrapyd部署spider  (标记)
 
 
2018.9.2

标签:

发表评论

电子邮件地址不会被公开。 必填项已用*标注