• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

python-scrapy(爬虫框架)

武飞扬头像
yzhSWJ
帮助1

(1)scrapy是什么?

Scrapy 是一个为了爬取网站数据,提取结构性数据而编写的应用框架。 可以应用在包括数据挖掘,信息处理 或存储历史数据等一系列的程序中
  1.  
    # (1) pip install scrapy
  2.  
    # (2) 报错1: building 'twisted.test.raiser' extension
  3.  
    # error: Microsoft Visual C 14.0 is required. Get it with "Microsoft Visual C
  4.  
    # Build Tools": http://landinghub.visualstudio.com/visual-cpp-build-tools
  5.  
    # 解决1
  6.  
    # http://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted
  7.  
    # Twisted‑20.3.0‑cp37‑cp37m‑win_amd64.whl
  8.  
    # cp是你的python版本
  9.  
    # amd是你的操作系统的版本
  10.  
    # 下载完成之后 使用pip install twisted的路径 安装
  11.  
    # 切记安装完twisted 再次安装scrapy
  12.  
     
  13.  
    # (3) 报错2 提示python -m pip install --upgrade pip
  14.  
    # 解决2 运行python -m pip install --upgrade pip
  15.  
     
  16.  
    # (4) 报错3 win32的错误
  17.  
    # 解决3 pip install pypiwin32
  18.  
     
  19.  
    # (5) anaconda

1.scrapy项目的创建以及运行

  1.  
    1. 创建爬虫的项目 scrapy startproject 项目的名字
  2.  
    注意:项目的名字不允许使用数字开头 也不能包含中文
  3.  
    2. 创建爬虫文件
  4.  
    要在spiders文件夹中去创建爬虫文件
  5.  
    cd 项目的名字\项目的名字\spiders
  6.  
    cd scrapy_百度_091\scrapy_百度_091\spiders
  7.  
     
  8.  
    创建爬虫文件
  9.  
    scrapy genspider 爬虫文件的名字 要爬取网页
  10.  
    eg:scrapy genspider 百度 http://www.百度.com
  11.  
    一般情况下不需要添加http协议 因为start_urls的值是根据allowed_domains
  12.  
    修改的 所以添加了http的话 那么start_urls就需要我们手动去修改了
  13.  
    3. 运行爬虫代码
  14.  
    scrapy crawl 爬虫的名字
  15.  
    eg:
  16.  
    scrapy crawl 百度

1.创建scrapy项目:

终端输入 scrapy startproject 项目名称

学新通

2.项目组成:

  spiders 
        __init__.py
                自定义的爬虫文件.py ‐‐‐》由我们自己创建,是实现爬虫核心功能的文件
        __init__.py
                items.py ‐‐‐》定义数据结构的地方,是一个继承自scrapy.Item的类
        middlewares.py ‐‐‐》中间件 代理
        pipelines.py ‐‐‐》管道文件,里面只有一个类,用于处理下载数据的后续处理 默认是300 优先级,值越小优先级越高(1‐1000)
         settings.py ‐‐‐》配置文件 比如:是否遵守robots 协议, User‐Agent 定义等

学新通

2. 创建爬虫文件

创建文件时,输入要爬取的网页地址

学新通

  1.  
    import scrapy
  2.  
     
  3.  
     
  4.  
    class BaiduSpider(scrapy.Spider):
  5.  
    # 爬虫的名字 用于运行爬虫的时候 使用的值
  6.  
    name = '百度'
  7.  
    # 允许访问的域名
  8.  
    allowed_domains = ['http://www.百度.com']
  9.  
    # 起始的url地址 指的是第一次要访问的域名
  10.  
    # start_urls 是在allowed_domains的前面添加一个http://
  11.  
    # 在 allowed_domains的后面添加一个/
  12.  
    start_urls = ['http://www.百度.com/']
  13.  
     
  14.  
    # 是执行了start_urls之后 执行的方法 方法中的response 就是返回的那个对象
  15.  
    # 相当于 response = urllib.request.urlopen()
  16.  
    # response = requests.get()
  17.  
    def parse(self, response):
  18.  
    print('苍茫的天涯是我的爱')

3.运行爬虫代码

scrapy crawl 爬虫名称
注意:应在 spiders 文件夹内执行

学新通

 反爬协议

学新通

scrapy项目的结构和response的属性和方法

  1.  
    1. scrapy项目的结构
  2.  
    项目名字
  3.  
    项目名字
  4.  
    spiders文件夹 (存储的是爬虫文件)
  5.  
    init
  6.  
    自定义的爬虫文件 核心功能文件 ****************
  7.  
    init
  8.  
    items 定义数据结构的地方 爬取的数据都包含哪些
  9.  
    middleware 中间件 代理
  10.  
    pipelines 管道 用来处理下载的数据
  11.  
    settings 配置文件 robots协议 ua定义等
  12.  
     
  13.  
    2. response的属性和方法
  14.  
    response.text 获取的是响应的字符串
  15.  
    response.body 获取的是二进制数据
  16.  
    response.xpath 可以直接是xpath方法来解析response中的内容
  17.  
    response.extract() 提取seletor对象的data属性值
  18.  
    response.extract_first() 提取的seletor列表的第一个数据

学新通

 demo

  1.  
    import scrapy
  2.  
     
  3.  
     
  4.  
    class TcSpider(scrapy.Spider):
  5.  
    name = 'tc'
  6.  
    allowed_domains = ['https://bj.58.com/sou/?key=前端开发']
  7.  
    start_urls = ['https://bj.58.com/sou/?key=前端开发']
  8.  
     
  9.  
    def parse(self, response):
  10.  
    # 字符串
  11.  
    # content = response.text
  12.  
    # 二进制数据
  13.  
    # content = response.body
  14.  
    # print('===========================')
  15.  
    # print(content)
  16.  
     
  17.  
    span = response.xpath('//div[@id="filter"]/div[@class="tabs"]/a/span')[0]
  18.  
    print('=======================')
  19.  
    print(span.extract())

demo2

  1.  
    import scrapy
  2.  
     
  3.  
     
  4.  
    class CarSpider(scrapy.Spider):
  5.  
    name = 'car'
  6.  
    allowed_domains = ['https://car.autohome.com.cn/price/brand-15.html']
  7.  
    # 注意如果你的请求的接口是html为结尾的 那么是不需要加/的
  8.  
    start_urls = ['https://car.autohome.com.cn/price/brand-15.html']
  9.  
     
  10.  
    def parse(self, response):
  11.  
    name_list = response.xpath('//div[@class="main-title"]/a/text()')
  12.  
    price_list = response.xpath('//div[@class="main-lever"]//span/span/text()')
  13.  
     
  14.  
    for i in range(len(name_list)):
  15.  
    name = name_list[i].extract()
  16.  
    price = price_list[i].extract()
  17.  
    print(name, price)

scrapy组织架构

学新通

 scrapy工作原理

学新通

 scrapy Shell(调试使用)

1.什么是scrapy shell

Scrapy 终端,是一个交互终端,供您在未启动 spider 的情况下尝试及调试您的爬取代码。 其本意是用来测试提取 数据的代码,不过您可以将其作为正常的Python 终端,在上面测试任何的 Python 代码。 该终端是用来测试XPath CSS 表达式,查看他们的工作方式及从爬取的网页中提取的数据。 在编写您的 spider 时,该 终端提供了交互性测试您的表达式代码的功能,免去了每次修改后运行spider 的麻烦。 一旦熟悉了Scrapy 终端后,您会发现其在开发和调试 spider 时发挥的巨大作用。

2.安装ipython

安装: pip install ipython
简介:如果您安装了 IPython Scrapy 终端将使用 IPython ( 替代标准 Python 终端 ) IPython 终端与其他相 比更为强大,提供智能的自动补全,高亮输出,及其他特性。

使用

  1.  
    # 进入到scrapy shell的终端 直接在window的终端中输入scrapy shell 域名
  2.  
    # 如果想看到一些高亮 或者 自动补全 那么可以安装ipython pip install ipython
  3.  
     
  4.  
     
  5.  
    # scrapy shell www.百度.com

学新通

 demo

学新通

yield

1. 带有 yield 的函数不再是一个普通函数,而是一个生成器 generator ,可用于迭代
2. yield 是一个类似 return 的关键字,迭代一次遇到 yield 时就返回 yield 后面 ( 右边 ) 的值。重点是:下一次迭代 时,从上一次迭代遇到的yield 后面的代码 ( 下一行 ) 开始执行
3. 简要理解: yield 就是 return 返回一个值,并且记住这个返回的位置,下次迭代就从这个位置后 ( 下一行 ) 开始
案例:
1. 当当网 (1) yield (2) . 管道封装(3) . 多条管道下载 (4)多页数据下载 2.电影天堂 (1)一个 item 包含多级页面的数据

1.自定义核心文件

  1.  
    import scrapy
  2.  
    # 不要看他报错,不影响下面调用方法
  3.  
    # 导入 scrapy_dangdang_095 下面的items
  4.  
    # from scrapy_dangdang_095.items import ScrapyDangdang095Item
  5.  
    # 解决导入函数报错
  6.  
    from ..items import ScrapyDangdang095Item
  7.  
     
  8.  
     
  9.  
    class DangSpider(scrapy.Spider):
  10.  
    name = 'dang'
  11.  
    # 如果是多页下载的话 那么必须要调整的是allowed_domains的范围 一般情况下只写域名
  12.  
    allowed_domains = ['category.dangdang.com']
  13.  
    start_urls = ['http://category.dangdang.com/cp01.01.02.00.00.00.html']
  14.  
     
  15.  
    base_url = 'http://category.dangdang.com/pg'
  16.  
    page = 1
  17.  
     
  18.  
    def parse(self, response):
  19.  
    # pipelines 下载数据
  20.  
    # items 定义数据结构的
  21.  
    # src = //ul[@id="component_59"]/li//img/@src
  22.  
    # alt = //ul[@id="component_59"]/li//img/@alt
  23.  
    # price = //ul[@id="component_59"]/li//p[@class="price"]/span[1]/text()
  24.  
    # 所有的seletor的对象 都可以再次调用xpath方法
  25.  
    li_list = response.xpath('//ul[@id="component_59"]/li')
  26.  
     
  27.  
    for li in li_list:
  28.  
    # 此处 图片是懒加载 所以获取的不是src
  29.  
    src = li.xpath('.//img/@data-original').extract_first()
  30.  
    # 第一张图片和其他的图片的标签的属性是不一样的
  31.  
    # 第一张图片的src是可以使用的 其他的图片的地址是data-original
  32.  
    # 第一张 返回的是None
  33.  
    if src:
  34.  
    src = src
  35.  
    else:
  36.  
    src = li.xpath('.//img/@src').extract_first()
  37.  
     
  38.  
    name = li.xpath('.//img/@alt').extract_first()
  39.  
    price = li.xpath('.//p[@class="price"]/span[1]/text()').extract_first()
  40.  
     
  41.  
    book = ScrapyDangdang095Item(src=src, name=name, price=price)
  42.  
     
  43.  
    # 获取一个book就将book交给pipelines
  44.  
    yield book
  45.  
     
  46.  
    # 每一页的爬取的业务逻辑全都是一样的,所以我们只需要将执行的那个页的请求再次调用parse方法
  47.  
    # 就可以了
  48.  
    # http://category.dangdang.com/pg2-cp01.01.02.00.00.00.html
  49.  
    # http://category.dangdang.com/pg3-cp01.01.02.00.00.00.html
  50.  
    # http://category.dangdang.com/pg4-cp01.01.02.00.00.00.html
  51.  
     
  52.  
    if self.page < 100:
  53.  
    self.page = self.page 1
  54.  
     
  55.  
    url = self.base_url str(self.page) '-cp01.01.02.00.00.00.html'
  56.  
     
  57.  
    # 怎么去调用parse方法
  58.  
    # scrapy.Request就是scrpay的get请求
  59.  
    # url就是请求地址
  60.  
    # callback是你要执行的那个函数 注意不需要加()
  61.  
    yield scrapy.Request(url=url, callback=self.parse)


2.配置items要爬取的数据

  1.  
    # Define here the models for your scraped items
  2.  
    #
  3.  
    # See documentation in:
  4.  
    # https://docs.scrapy.org/en/latest/topics/items.html
  5.  
     
  6.  
    import scrapy
  7.  
     
  8.  
     
  9.  
    class ScrapyDangdang095Item(scrapy.Item):
  10.  
    # define the fields for your item here like:
  11.  
    # name = scrapy.Field()
  12.  
    # 通俗的说就是你要下载的数据都有什么
  13.  
     
  14.  
    # 图片
  15.  
    src = scrapy.Field()
  16.  
    # 名字
  17.  
    name = scrapy.Field()
  18.  
    # 价格
  19.  
    price = scrapy.Field()
  20.  
     

3.使用管道 pipelines

  1.  
    # Define your item pipelines here
  2.  
    #
  3.  
    # Don't forget to add your pipeline to the ITEM_PIPELINES setting
  4.  
    # See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html
  5.  
     
  6.  
     
  7.  
    # useful for handling different item types with a single interface
  8.  
    from itemadapter import ItemAdapter
  9.  
     
  10.  
     
  11.  
    # 如果想使用管道的话 那么就必须在settings中开启管道
  12.  
    class ScrapyDangdang095Pipeline:
  13.  
    # 在爬虫文件开始的之前就执行的一个方法
  14.  
    def open_spider(self, spider):
  15.  
    self.fp = open('book.json', 'w', encoding='utf-8')
  16.  
     
  17.  
    # item就是yield后面的book对象
  18.  
    def process_item(self, item, spider):
  19.  
    # 以下这种模式不推荐 因为每传递过来一个对象 那么就打开一次文件 对文件的操作过于频繁
  20.  
     
  21.  
    # # (1) write方法必须要写一个字符串 而不能是其他的对象
  22.  
    # # (2) w模式 会每一个对象都打开一次文件 覆盖之前的内容
  23.  
    # with open('book.json','a',encoding='utf-8')as fp:
  24.  
    # fp.write(str(item))
  25.  
    # 请使用此方法
  26.  
    self.fp.write(str(item))
  27.  
     
  28.  
    return item
  29.  
     
  30.  
    # 在爬虫文件执行完之后 执行的方法
  31.  
    def close_spider(self, spider):
  32.  
    self.fp.close()
  33.  
     
  34.  
     
  35.  
    import urllib.request
  36.  
     
  37.  
     
  38.  
    # 多条管道开启,下载图片
  39.  
    # (1) 定义管道类
  40.  
    # (2) 在settings中开启管道
  41.  
    # 'scrapy_dangdang_095.pipelines.DangDangDownloadPipeline':301
  42.  
    class DangDangDownloadPipeline:
  43.  
    def process_item(self, item, spider):
  44.  
    url = 'http:' item.get('src')
  45.  
    filename = './books/' item.get('name') '.jpg'
  46.  
     
  47.  
    urllib.request.urlretrieve(url=url, filename=filename)
  48.  
     
  49.  
    return item

注意:要是用pipelines 要在settings 中开启

学新通

 获取列表和详情

学新通

 详情地址

学新通

  1.  
    import scrapy
  2.  
     
  3.  
    from ..items import ScrapyMovie099Item
  4.  
     
  5.  
     
  6.  
    class MvSpider(scrapy.Spider):
  7.  
    name = 'mv'
  8.  
    allowed_domains = ['www.dytt8.net']
  9.  
    start_urls = ['https://www.dytt8.net/html/gndy/china/index.html']
  10.  
     
  11.  
    def parse(self, response):
  12.  
    # 要第一个的名字 和 第二页的图片
  13.  
    a_list = response.xpath('//div[@class="co_content8"]//td[2]//a[2]')
  14.  
     
  15.  
    for a in a_list:
  16.  
    # 获取第一页的name 和 要点击的链接
  17.  
    name = a.xpath('./text()').extract_first()
  18.  
    href = a.xpath('./@href').extract_first()
  19.  
     
  20.  
    # 第二页的地址是
  21.  
    url = 'https://www.dytt8.net' href
  22.  
     
  23.  
    # 对第二页的链接发起访问
  24.  
    yield scrapy.Request(url=url, callback=self.parse_second, meta={'name': name})
  25.  
     
  26.  
    def parse_second(self, response):
  27.  
    # 注意 如果拿不到数据的情况下 一定检查你的xpath语法是否正确
  28.  
    # 详情页src
  29.  
    src = response.xpath('//div[@id="Zoom"]//img/@src').extract_first()
  30.  
    # 接受到请求的那个meta参数的值,外页面列表name
  31.  
    name = response.meta['name']
  32.  
     
  33.  
    movie = ScrapyMovie099Item(src=src, name=name)
  34.  
    # 发给管道
  35.  
    yield movie

CrawlSpider

1. 继承自 scrapy.Spider
2. 独门秘笈
CrawlSpider 可以定义规则,再解析 html 内容的时候,可以根据链接规则提取出指定的链接,然后再向这些链接发 送请求
所以,如果有需要跟进链接的需求,意思就是爬取了网页之后,需要提取链接再次爬取,使用 CrawlSpider 是非常 合适的
学新通

 运行原理

学新通

 CrawlSpider案例

学新通

 学新通

1.创建项目:scrapy startproject dushuproject
2.跳转到spiders路径 cd\dushuproject\dushuproject\spiders
注意:此处多了一个 ‐t crawl
3.创建爬虫类:scrapy genspider ‐t crawl read www.dushu.com

demo

自定义核心文件

  1.  
    import scrapy
  2.  
    from scrapy.linkextractors import LinkExtractor
  3.  
    from scrapy.spiders import CrawlSpider, Rule
  4.  
     
  5.  
    from ..items import ScrapyReadbook101Item
  6.  
     
  7.  
     
  8.  
    class ReadSpider(CrawlSpider):
  9.  
    name = 'read'
  10.  
    allowed_domains = ['www.dushu.com']
  11.  
    # 注意第一页的数据1188_1 中的_1 不要漏掉
  12.  
    start_urls = ['https://www.dushu.com/book/1188_1.html']
  13.  
    # allow 提取页面符合要求所有连接
  14.  
    # follow=True 如果是false 只会获取当前显示页的所有数据 13 页
  15.  
    # follow=True 会获取全部页数据
  16.  
    rules = (
  17.  
    Rule(LinkExtractor(allow=r'/book/1188_\d .html'),
  18.  
    callback='parse_item',
  19.  
    follow=True),
  20.  
    )
  21.  
     
  22.  
    def parse_item(self, response):
  23.  
     
  24.  
    img_list = response.xpath('//div[@class="bookslist"]//img')
  25.  
     
  26.  
    for img in img_list:
  27.  
    name = img.xpath('./@data-original').extract_first()
  28.  
    src = img.xpath('./@alt').extract_first()
  29.  
     
  30.  
    book = ScrapyReadbook101Item(name=name,src=src)
  31.  
    yield book
  32.  
     
  33.  
     
  34.  
     

将查询的数据存入数据库中

需要安装  pymysql 包
pymysql 的使用步骤

1.pip install pymysql

2.pymysql.connect(host,port,user,password,db,charset)
3.conn.cursor()
4.cursor.execute()

2.setting配置mysql信息/以及新建通道

学新通

 3.通道pipelines

  1.  
    # Define your item pipelines here
  2.  
    #
  3.  
    # Don't forget to add your pipeline to the ITEM_PIPELINES setting
  4.  
    # See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html
  5.  
     
  6.  
     
  7.  
    # useful for handling different item types with a single interface
  8.  
    from itemadapter import ItemAdapter
  9.  
     
  10.  
     
  11.  
    class ScrapyReadbook101Pipeline:
  12.  
     
  13.  
    def open_spider(self, spider):
  14.  
    self.fp = open('book.json', 'w', encoding='utf-8')
  15.  
     
  16.  
    def process_item(self, item, spider):
  17.  
    self.fp.write(str(item))
  18.  
    return item
  19.  
     
  20.  
    def close_spider(self, spider):
  21.  
    self.fp.close()
  22.  
     
  23.  
     
  24.  
    # 加载settings文件
  25.  
    from scrapy.utils.project import get_project_settings
  26.  
    import pymysql
  27.  
     
  28.  
     
  29.  
    class MysqlPipeline:
  30.  
     
  31.  
    def open_spider(self, spider):
  32.  
    settings = get_project_settings()
  33.  
    self.host = settings['DB_HOST']
  34.  
    self.port = settings['DB_PORT']
  35.  
    self.user = settings['DB_USER']
  36.  
    self.password = settings['DB_PASSWROD']
  37.  
    self.name = settings['DB_NAME']
  38.  
    self.charset = settings['DB_CHARSET']
  39.  
     
  40.  
    self.connect()
  41.  
     
  42.  
    def connect(self):
  43.  
    self.conn = pymysql.connect(
  44.  
    host=self.host,
  45.  
    port=self.port,
  46.  
    user=self.user,
  47.  
    password=self.password,
  48.  
    db=self.name,
  49.  
    charset=self.charset
  50.  
    )
  51.  
     
  52.  
    self.cursor = self.conn.cursor()
  53.  
     
  54.  
    def process_item(self, item, spider):
  55.  
    sql = 'insert into book(name,src) values("{}","{}")'.format(item['name'], item['src'])
  56.  
    # 执行sql语句
  57.  
    self.cursor.execute(sql)
  58.  
    # 提交
  59.  
    self.conn.commit()
  60.  
     
  61.  
    return item
  62.  
     
  63.  
    def close_spider(self, spider):
  64.  
    self.cursor.close()
  65.  
    self.conn.close()

日志信息和日志等级

学新通

 学新通

 scrapy的post请求

学新通

 自定义核心文件

  1.  
    import scrapy
  2.  
     
  3.  
    import json
  4.  
     
  5.  
     
  6.  
    class TestpostSpider(scrapy.Spider):
  7.  
    name = 'testpost'
  8.  
    allowed_domains = ['https://fanyi.百度.com/sug']
  9.  
     
  10.  
    # post请求 如果没有参数 那么这个请求将没有任何意义
  11.  
    # 所以start_urls 也没有用了
  12.  
    # parse方法也没有用了
  13.  
    # start_urls = ['https://fanyi.百度.com/sug/']
  14.  
    #
  15.  
    # def parse(self, response):
  16.  
    # pass
  17.  
     
  18.  
    def start_requests(self):
  19.  
    url = 'https://fanyi.百度.com/sug'
  20.  
     
  21.  
    data = {
  22.  
    'kw': 'final'
  23.  
    }
  24.  
     
  25.  
    yield scrapy.FormRequest(url=url, formdata=data, callback=self.parse_second)
  26.  
     
  27.  
    def parse_second(self, response):
  28.  
    content = response.text
  29.  
    # json 不需要 ,encoding='utf-8'
  30.  
    obj = json.loads(content)
  31.  
     
  32.  
    print(obj)

代理

学新通

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgfifgf
系列文章
更多 icon
同类精品
更多 icon
继续加载