Python排虫 之使用 Scrapy 框架实现获取 腾讯视频信息 并上传到 Mysql数据库

摘要:

      如果我们把互联网比作一张大的蜘蛛网,数据便是存放于蜘蛛网的各个节点;而爬虫就是一只小蜘蛛,沿着网络抓取自己的猎物(数据)爬虫指的是:向网站发起请求,获取资源后分析并提取有用数据的程序;从技术层面来说就是 通过程序模拟浏览器请求站点的行为,把站点返回的HTML代码/JSON数据/二进制数据(图片、视频) 爬到本地,进而提取自己需要的数据,存放起来使用;


友情提示:

 本文所有关于 python 的基本代码都是基于 python3.7 的,不同 python 版本之间会有些许差异,但不影响我们对 整体的把握和了解。

    由于 本文的源代码实现依赖于python源代码,所以阅读本文需要读者了解关python的基本语法,关于python基本语法 请移步菜鸟教程  http://www.runoob.com/python/python-tutorial.html,以及还有mysql的基本操作,需要读者有基本的了解


一. Scrapy概述

 

  • Scrapy是用纯Python实现一个为了爬取网站数据、提取结构性数据而编写的应用框架,用途非常广泛。

  • 框架的力量,用户只需要定制开发几个模块就可以轻松的实现一个爬虫,用来抓取网页内容以及各种图片,非常之方便。

 

我们在项目中主要用到了如下加黑的部分

  • Scrapy Engine(引擎): 负责Spider、ItemPipeline、Downloader、Scheduler中间的通讯,信号、数据传递等。

  • Scheduler(调度器): 它负责接受引擎发送过来的Request请求,并按照一定的方式进行整理排列,入队,当引擎需要时,交还给引擎。

  • Downloader(下载器):负责下载Scrapy Engine(引擎)发送的所有Requests请求,并将其获取到的Responses交还给Scrapy Engine(引擎),由引擎交给Spider来处理,

  • Spider(爬虫):它负责处理所有Responses,从中分析提取数据,获取Item字段需要的数据,并将需要跟进的URL提交给引擎,再次进入Scheduler(调度器)

  • Item Pipeline(管道):它负责处理Spider中获取到的Item,并进行进行后期处理(详细分析、过滤、存储等)的地方.

  • Downloader Middlewares(下载中间件):你可以当作是一个可以自定义扩展下载功能的组件。

  • Spider Middlewares(Spider中间件):你可以理解为是一个可以自定扩展和操作引擎和Spider中间通信的功能组件(比如进入Spider的Responses;和从Spider出去的Requests)

引用链接:https://www.jianshu.com/p/306e03c618cf


二. 安装python

       下载地址:https://www.python.org/downloads/windows/

       本文项目环境:window10

       python版本: Windows x86-64 executable installer


三、安装pycharm

      下载地址:https://www.jetbrains.com/pycharm/download/#section=windows,并选择window版本安装


四、安装 scrapy 框架

有一点 不要在pycharm上直接安装 scrapy 不知道因为什么一直失败,莫名的尴尬

我们直接在  C:\Users\jie\AppData\Local\Programs\Python\Python37\Scripts   这个scripts目录下打开cmd安装

  • 首先看这个方法能不能成功:pip install scrapy
  • 如果使用上面的命令太慢。国内可以使用豆瓣源进行加速:pip install -i  https://pypi.douban.com/simple scrapy 

1、如果失败考虑安装whl格式的包:

        如果安装whl格式包则需要安装wheel库,安装方法:pip install wheel

2、由于scrapy依赖twiste,先要安装twiste:

      下载地址:https://www.lfd.uci.edu/~gohlke/pythonlibs/  

       在网页中搜索twisted找到对应的whl包并下载:Twisted‑18.4.0‑cp37‑cp37m‑win_amd64.whl

       根据Python版本选择合适的包,名称中间的cp37是python3.7的意思,amd64是python的位数)

      下载完成后使用cmd命令打开windows的命令行窗口,进入whl包所在的文件夹执行如下命令:pip install [whl]

      [whl]是whl包的名字,即:pip install Twisted‑18.4.0‑cp36‑cp36m‑win_amd64.whl


3、scrapy依赖lxml包,安装lxml: pip install lxml

4、下载地址:https://www.lfd.uci.edu/~gohlke/pythonlibs/  在网页中搜索scrapy下载scrapy的whl包         

      Scrapy‑1.5.0‑py2.py3‑none‑any.whl      

      下载完成后使用cmd命令打开windows的命令行窗口,进入whl包所在的文件夹执行如下命令:pip install [whl]

      [whl]是whl包的名字,即:pip install Scrapy‑1.5.0‑py2.py3‑none‑any.whl

这样安装一定成功

然后使用 pycharm 记得先在 file -》setting 中更改为你的 python 环境

这样环境就算是安装完成了


五、创建项目(如下代码为demo)

5.1创建一个新项目 demo1

5.2 代建 scrapy 框架

创建 Tengxun 在 编辑器底部栏的 terminal 终端 中输入

scrapy startproject Tengxun


5.3 分析我们要做什么操作,以如下几点

  1. 新建项目 (scrapy startproject xxx):新建一个新的爬虫项目
  2. 明确目标 (编写items.py):明确你想要抓取的目标
  3. 制作爬虫 (spiders/xxspider.py):制作爬虫开始爬取网页
  4. 存储内容 (pipelines.py):设计管道存储爬取内容

5.4 修改setting的代码 ,在setting 文件夹下加入如下 code


# 函数的执行顺序,序号越小,优先级越高
ITEM_PIPELINES = {
   'HupuSpider.pipelines.HupuspiderPipeline': 1,
   'HupuSpider.pipelines.HupuImagesPipeline': 2,
}
LOG_LEVEL='DEBUG'
ROBOTSTXT_OBEY = True

5.5 创建 item 

import scrapy

class HupuspiderItem(scrapy.Item): (注意这里的类名你需要根据自己的命名做更改)
    # 明星名称
    starname = scrapy.Field()
    # 明星url
    starurl = scrapy.Field()
    # 简介内容
    content=scrapy.Field()
    # 简介标题
    contenttitle=scrapy.Field()
    # 拍的电影图片
    imageurl=scrapy.Field()

5.6 爬取我们想要获得数据的网页,进而分析

创建如下文件

import scrapy

class demoSpider(scrapy.Spider):
    name = "dmoz"
    allowed_domains = ["dmoz.org"]
    start_urls = [
        "http://www.dmoz.org/Computers/Programming/Languages/Python/Books/",
        "http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/"
    ]

    def parse(self, response):
        filename = response.url.split("/")[-2] + '.html'
        with open(filename, 'wb') as f:
            f.write(response.body)

获取到html 然后 我们在对其进行分析

5.7 编写我们的逻辑代码 (刚刚创建的文件中)

# -*- coding: utf-8 -*-
from HupuSpider.items import HupuspiderItem
import scrapy
import os

class NbaNewsSpider(scrapy.Spider):
    name = 'tengxun'
    # allowed_domains = ['v.qq.com/x/hotlist/search/?channel=556']
    start_urls = ['https://v.qq.com/x/hotlist/search/?channel=556']
    def parse(self, response):
        # 抓取响应体
        # filename = response.url.split("/")[-5] + '.html'
        # print(response.extract())
        # with open(filename, 'wb') as f:
        #      f.write(response.body)

        # 明星排行榜单
        result = response.xpath('/html/body/div[3]/div[1]/div[1]/div[2]/ul/li/div[1]/a')
        # print(result.extract())
        # 榜单明星名字
        startman  = result.xpath('.//text()').extract()
        # print(startman)

        # 榜单明星具体信息地址
        startmanurl = result.xpath('.//@href').extract()
        # print(startmanurl)
        # 存放 bean 数据
        items = []
        # 创建明星目录
        for i in range(0,len(startman)):
            item = HupuspiderItem()

            # 指定存储目录+明星名字
            teamFilename="./今日明星/"+startman[i]

            # 如果目录不存在,则创建目录
            if (not os.path.exists(teamFilename)):
                os.makedirs(teamFilename)

            item['starname']=startman[i]
            item['starurl']=startmanurl[i]

            items.append(item)
        # print(items)

        # #发送每个明星的url的Request请求,得到Response连同包含meta数据
        # # 一同交给回调函数 second_parse 方法处理
        for item in items:
            for i in range(1,2):
                # tempurl = item['starurl'].replace('.html','')
                # teamurl = tempurl + '-' + str(i) + '.html'
                yield scrapy.Request(url=item['starurl'], meta={'meta_1': item}, callback=self.second_parse)

    # 对每支球队的url进行爬取
    def second_parse(self,response):
        # items = 0
        # 提取每次Response的meta数据(就是上个函数保存下来的)
        item = response.meta['meta_1']
        # 获得明星个人简介
        temp = response.css('.desc_text').xpath('string(.)').extract()[0]
        item['content'] = temp
        # print(temp)
        # 明星个人电影图片
        temp = "";
        imaurl = response.xpath('/html/body/div[2]/div[2]/div[1]/div[2]/div[2]/div[2]/div[1]/div[1]/ul/li/a/img/@src').extract()
        for i in range(0, len(imaurl)):
            temp = temp+","+imaurl[i]
        item['imageurl'] = temp
        item['contenttitle'] = item['starname']
        yield item

5.8 在 pipelines 文件中编写item 的处理(含有创建 txt 文件,图片下载处理,上传信息到数据库)

# -*- coding: utf-8 -*-
from scrapy.pipelines.images import ImagesPipeline
from scrapy.utils.project import get_project_settings
import scrapy
import shutil
import pymysql
import os

class HupuspiderPipeline(object):
    def process_item(self, item, spider):
        # 明星名字作为简介txt的名字
        filename = item['contenttitle']
        filename += ".txt"

        # 个人简介放到个人相对应的文件夹中
        savepath='./今日明星'+'/'+item['starname']+'/'+filename
        fp = open(savepath, 'w', encoding='utf-8')
        fp.write(item['content'])
        fp.close()

        host = '127.0.0.1'
        user = 'root'
        psd = 'root'
        db = "python"
        c = "utf8"
        port = 3306
        # 数据库连接
        con = pymysql.connect(host=host, user=user, passwd=psd, db=db, charset=c, port=port)
        # 数据库游标
        cue = con.cursor()
        print("mysql connect succes")  # 测试语句,这在程序执行时非常有效的理解程序是否执行到这一步
        try:
            cue.execute("insert into news (name,content) values(%s,%s)",
                        [item['starname'], item['content']])
            print("insert success")  # 测试语句
        except Exception as e:
            print('Insert error:', e)
            con.rollback()
        else:
            con.commit()
        con.close()

        return item

class HupuImagesPipeline(ImagesPipeline):
    # 重写ImagesPipeline类的此方法
    # 发送图片下载请求
    def get_media_requests(self, item, info):
        image_url = item["imageurl"]
        str = image_url.split(',')
        for i in range(1, len(str)-1):
            yield scrapy.Request("http:"+str[i])

    # 重写item_completed方法
    # 将下载的文件保存到不同的目录中
    def item_completed(self, results, item, info):
        # 从项目设置文件中导入图片下载路径
        IMAGES_STORE = get_project_settings().get("IMAGES_STORE")
        # 固定写法,获取图片路径,同时判断这个路径是否正确,如果正确,
        for i in range(0,len(results)):
            os.rename(IMAGES_STORE + '/' + results[i][1]['path'],  IMAGES_STORE + '/' + item['starname'] + str(i) + '.jpg')
            shutil.move(IMAGES_STORE + '/' + item['starname'] + str(i) +'.jpg', './今日明星' + '/' + item['starname'])

    def __del__(self):
        IMAGES_STORE = get_project_settings().get("IMAGES_STORE")
         # 完成后删除整个full目录
        shutil.rmtree(IMAGES_STORE + '/' + 'full')
        shutil.rmtree(IMAGES_STORE)

        5.8.1 创建 txt 代码

        filename = item['contenttitle']
        filename += ".txt"

        # 个人简介放到个人相对应的文件夹中
        savepath='./今日明星'+'/'+item['starname']+'/'+filename
        fp = open(savepath, 'w', encoding='utf-8')
        fp.write(item['content'])
        fp.close()

       5.8.2 图片下载的代码

   # 重写ImagesPipeline类的此方法
    # 发送图片下载请求
    def get_media_requests(self, item, info):
        image_url = item["imageurl"]
        str = image_url.split(',')
        for i in range(1, len(str)-1):
            yield scrapy.Request("http:"+str[i])

    # 重写item_completed方法
    # 将下载的文件保存到不同的目录中
    def item_completed(self, results, item, info):
        # 从项目设置文件中导入图片下载路径
        IMAGES_STORE = get_project_settings().get("IMAGES_STORE")
        # 固定写法,获取图片路径,同时判断这个路径是否正确,如果正确,
        for i in range(0,len(results)):
            os.rename(IMAGES_STORE + '/' + results[i][1]['path'],  IMAGES_STORE + '/' + item['starname'] + str(i) + '.jpg')
            shutil.move(IMAGES_STORE + '/' + item['starname'] + str(i) +'.jpg', './今日明星' + '/' + item['starname'])

    def __del__(self):
        IMAGES_STORE = get_project_settings().get("IMAGES_STORE")
         # 完成后删除整个full目录
        shutil.rmtree(IMAGES_STORE + '/' + 'full')
        shutil.rmtree(IMAGES_STORE)

         5.8.3  数据上传到 mysql

  host = '127.0.0.1'
        user = 'root'
        psd = 'root'
        db = "python"
        c = "utf8"
        port = 3306
        # 数据库连接
        con = pymysql.connect(host=host, user=user, passwd=psd, db=db, charset=c, port=port)
        # 数据库游标
        cue = con.cursor()
        print("mysql connect succes")  # 测试语句,这在程序执行时非常有效的理解程序是否执行到这一步
        try:
            cue.execute("insert into news (name,content) values(%s,%s)",
                        [item['starname'], item['content']])
            print("insert success")  # 测试语句
        except Exception as e:
            print('Insert error:', e)
            con.rollback()
        else:
            con.commit()
        con.close()

六、效果展示

      6.1

   6.2


 

参考

http://www.runoob.com/python/python-tutorial.html

https://scrapy-chs.readthedocs.io/zh_CN/1.0/intro/overview.html 

 

 

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python Scrapy是一种优秀的开源网络爬虫框架,可以用于从网页中爬取数据。借助其强大的功能,我们可以轻松地将爬取到的数据写入数据库。 首先,我们需要创建一个Scrapy项目并配置好爬虫。在项目中,我们可以定义Item类来表示我们需要提取的数据字段。通过编写爬虫规则,我们可以指定要爬取的网页、需要提取的数据字段以及数据的处理方式。 在编写完爬虫规则后,Scrapy会自动将爬取到的数据封装成Item对象。我们可以在爬虫的回调函数中对这些Item对象进行处理,例如将数据写入数据库。 为了将数据写入数据库,我们可以使用Python数据库操作库,如MySQLdb或者pymysql。首先,我们需要连接到数据库,并创建一个数据库连接对象。然后,我们可以将爬取到的数据逐条插入到数据库中。 插入数据的具体步骤如下: 1. 导入数据库操作库 2. 连接到数据库 3. 创建游标对象 4. 遍历爬取到的数据 5. 构造插入语句 6. 执行插入操作 7. 提交事务 8. 关闭游标和数据库连接 通过以上步骤,我们可以将爬取到的数据成功写入数据库。 值得注意的是,在爬取大量数据时,为了提高性能和效率,我们可以使用异步IO库,如aiomysql或aiopg,来实现异步插入操作。 总而言之,Python Scrapy可以轻松实现数据的网页爬取,并通过数据库操作库将数据写入数据库。这样,我们可以方便地对爬取到的数据进行存储和管理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值