• Scrapy 爬取网站文章


    新建scrapy

      scrapy startproject ArticleSpider

    创建spider

      cd ArticleSpider

      scrapy genspider jobbole http://blog.jobbole.com

      scrapy genspider -t crawl lagou www.lagou.com #指定生成的模板-t crawl        scrapy genspider --list 查看生成spider可以使用的模板

      pip install pypiwin32

    在pycharm中open该项目

      在该目录下添加main.py 用于执行爬虫代码

      setting.py中修改内容 ROBOTSTXT_OBEY = False
    from scrapy.cmdline import execute
    
    import sys
    import os
    #得到项目路径
    sys.path.append(os.path.dirname(os.path.abspath(__file__)))
    #传递执行命令
    execute(["scrapy","crawl","jobbole"])

    在cmd下可以执行 scrapy crawl jobbole 或者使用pycharm执行main.py文件 便可以正常使用pycharm调试爬虫程序

    在cmd下进行页面的调试比pycharm的debug更方便             scrapy shell http://blog.jobbole.com/112801/

    XPATH语法

    cmd: title = response.xpath('//*[@id="post-112801"]/div[1]/h1/text()') 加粗部分代码是使用chrome的调试工具里面复制的xpath 直接获取里边的内容

    cmd: title.extract() 返回的是一个python list

      title.extract()[0].strip() 将多余的符号删除

      title.extract()[0].strip().replace("X","Y") 将不需要的字符替换掉

    CSS选择器

    response.css(".entry-header h1::text").extract()

    爬虫就是将非结构化的html解析成自定义结构的数据

    最简单的就是保存到sql

    1.定义items.py

    name = scrapy.Field()#可以定义一个函数对Field里面的值进行转换lambda X:X + “author” 就可以将取到的值进行添加author操作

    2.在setting文件中使得pipelines生效

    ITEM_PIPELINES = {
       'ArticleSpider.pipelines.ArticlespiderPipeline': 300,
    }

    3.这样spider里面yield的item就可以传递到pipelines

    name = request.css(XXXXXXXXXXXX).extract_first("")
    article = XXXitem()
    article["name"] = scrapy.Field()
    yield article#yield可以将此处生成的article对象传到pipelines里面

    4.配置自动下载图片 setting

    ITEM_PIPELINES = {
       'ArticleSpider.pipelines.ArticlespiderPipeline': 300,
        'scrapy.pipelines.images.ImagesPipeline': 1,
    }
    IMAGES_URLS_FIELD = "front_image_url"
    
    project_dir = os.path.abspath(os.path.dirname(__file__))
    IMAGES_STORE = os.path.join(project_dir, "images")#到此   设置只能讲图片保存到指定路径但是 如果需要拿出指定文章的指定图片还是不可以

    提取图片路径(定制自制pipeline)

    class ArticleImagePipeline(ImagesPipeline):
        #重载该函数获取保存image的path
        def item_completed(self, results, item, info):
    
            for ok, result in results:
                image_file_path = result["path"]
    
            item["front_image_path"] = image_file_path
            return item
    #配置pipeline执行顺序
    'ArticleSpider.pipelines.ArticleImagePipeline': 1,
     
     'ArticleSpider.pipelines.MysqlTwistedPipeline': 300,#进行保存的pipeline 设置一个大的值 执行顺序由小到大 

    将内容保存到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) + '
    '
            self.file.write(lines)
            return item
        def spider_closed(self, spider):
            self.file.close()

    将内容保存到mysql中要在虚拟环境中添加mysqlclient pip install mysqlclient(window)  centos下 sudo yum install python-devel mysql-devel    ubuntu下 sudo apt-get install libmysqlclient-dev

    #python 插入mysql方法
    class MysqlClientPipeline(object):
        def __init__(self):
            self.conn = MySQLdb.connect('127.0.0.1', 'root', '', 'jobbole', charset="utf8", use_unicode=True)
            self.cursor = self.conn.cursor()
    
        def process_item(self, item, spider):
            insert_sql = """insert into jobbole_article(title, url, create_date, fav_nums) VALUES(%s, %s, %s, %s)"""
            self.cursor.execute(insert_sql, (item["title"], item["url"], item["create_date"], item["fav_nums"]))
            self.conn.commit()

    scrapy ItemLoader 

    item_loader = ItemLoader(item=XXXItem(), response=response)
    #三种add方法替换原先的css选择器 xpath 以及赋值
    item_loader.add_css("title", ".entry-header h1::text")
    item_loader.add_value("url", response.url)
    item_loader.add_xpath("url", response.url)

    XXX_item = item_loader.load_item()#直接使用ItemLoader返回的XXXItem里边的属性值都是list(不确定在html中提取的值为一个)要改变list成为值就需要 自定义ItemLoader如下
    from scrapy.loader.processors import  TakeFirst
    from scrapy.loader import  ItemLoader
    class XXXItemLoader(ItemLoader):
        #自定义itemloader   将输出改变 由原来的list 改变成第一个元素
        default_output_processor = TakeFirst()
    
    #在spider里边调用
    item_loader = XXXItemLoader(item=JobBoleArticleItem(), response=response)
    #这样得到的item里面的值便不是list

    Scrapy 架构图 来自官方文档 为理解流程重新绘制

  • 相关阅读:
    [Z]芯片设计经验
    ADF4350初始化程序(verilog)
    基于Altera FPGA的LVDS配置应用一例
    M4K使用率
    榨干FPGA片上存储资源
    ios通讯录复制出来的电话号码两端有隐藏字符串
    PHP做APP接口时,如何保证接口的安全性
    【PHP】微信开放平台---消息加解密-php7.1 使用openssl代替Mcrypt
    Gram矩阵(pytorch)
    数据库范式
  • 原文地址:https://www.cnblogs.com/wlc297984368/p/7784049.html
Copyright © 2020-2023  润新知