社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

如何用 Python + Scrapy 爬取视频?

黑客技术和网络安全 • 4 年前 • 452 次点击  
👇👇关注后回复 “进群” ,拉你进程序员交流群👇👇
作者丨快快
来源丨快学Python

人生苦短,快学Python!
今天将带大家简单了解Scrapy爬虫框架,并用一个真实案例来演示代码的编写和爬取过程。

(完整代码下载见文末)

一、scrapy简介

1. 什么是Scrapy

Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架,我们只需要实现少量的代码,就能够快速的抓取

Scrapy使用了Twisted异步网络框架,可以加快我们的下载速度

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

异步和非阻塞的区别

异步:调用在发出之后,这个调用就直接返回,不管有无结果

非阻塞:关注的是程序在等待调用结果时的状态,指在不能立刻得到结果之前,该调用不会阻塞当前线程

2. Scrapy工作流程

另一种爬虫方式

Scrapy工作流程

Scrapy engine(引擎)总指挥:负责数据和信号的在不同模块间的传递scrapy已经实现
Scheduler(调度器)一个队列,存放引擎发过来的request请求scrapy已经实现
Downloader(下载器)下载把引擎发过来的requests请求,并返回给引擎scrapy已经实现
Spider(爬虫)处理引擎发来的response,提取数据,提取url,并交给引擎需要手写
Item Pipline(管道)处理引擎传过来的数据,比如存储需要手写
Downloader Middlewares(下载中间件)可以自定义的下载扩展,比如设置代理一般不用手写
Spider Middlewares(中间件)可以自定义requests请求和进行response过滤一般不用手写

3. Scrapy入门

#1 创建一个scrapy项目
scrapy startproject mySpider

#2 生成一个爬虫
scrapy genspider demo "demo.cn"

#3 提取数据
完善spider 使用xpath等

#4 保存数据
pipeline中保存数据

在命令中运行爬虫

scrapy crawl qb     # qb爬虫的名字

在pycharm中运行爬虫

from scrapy import cmdline

cmdline.execute("scrapy crawl qb".split())

4. pipline使用

pipeline的字典形可以看出来,pipeline可以有多个,而且确实pipeline能够定义多个

为什么需要多个pipeline:

1 可能会有多个spider,不同的pipeline处理不同的item的内容

2 一个spider的内容可以要做不同的操作,比如存入不同的数据库中

注意:

1 pipeline的权重越小优先级越高

2 pipeline中process_item方法名不能修改为其他的名称

5. 文件目录结构

文件配置:

setting:

SPIDER_MODULES = ['st.spiders']
NEWSPIDER_MODULE = 'st.spiders'
LOG_LEVEL = 'WARNING' # 这样设置可以在运行的时候不打印日志文件
...
# Obey robots.txt rules
ROBOTSTXT_OBEY = False # 调整为false,
...
# Override the default request headers: # 头部信息,反爬
DEFAULT_REQUEST_HEADERS = {
    'user-agent''Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36',
  'Accept''text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
  'Accept-Language''en',
}
...
ITEM_PIPELINES = { # 打开管道
    'st.pipelines.StPipeline'300,
}

为了运行文件方便:新建start.py(和settings在同一目录下),

from scrapy import cmdline
cmdline.execute('scrapy crawl stsp'.split()) # 这里爬虫项目名为stsp

目前是这样,后面提取数据的时候修改对应文件 .

二、页面分析

第一页url:https://699pic.com/video-sousuo-0-18-0-0-0-1-4-popular-0-0-0-0-0-0.html

url规律:

url = 'https://699pic.com/video-sousuo-0-18-0-0-0-{}-4-popular-0-0-0-0-0-0.html'.format(i)

通过分析页面知道视频数据在li里面,如图所示.现在问题就简单了。

二、解析数据

def parse(self, response):
    # global count
    # count += 1
    # print(response)
    liList = response.xpath('//li'# 获取所有的li,后面提取有用的
    
    print(len(liList)) # 76(然后分析可知,第11个到第70个是我们需要的数据)
    
    newfolderName = 'page{}'.format(count) # 文件夹的名字page1,page2,....
    # 步骤二 创建一个新的文件夹 保存每页的视频
    if not os.path.exists(newfolderName):
        os.mkdir(newfolderName)

    for li in liList[10:-6]:
        video_link = li.xpath("./a/div/video/@data-original").extract_first()
        videoLink = 'https:' + video_link # url拼接
        title = li.xpath("./a[2]/h3/text()").extract_first()
        # 下载数据:
        res = requests.get(videoLink,headers=headers)
        data = res.content
               
        try:
            with open(newfolderName + '/' + title + '.mp4','wb'as f:
                 f.write(data)
                 print('%s下载成功'%title)
        except:
           break

三、文件配置

items:

import scrapy
class StItem(scrapy.Item):
    # define the fields for your item here like:
    # 和两个对应前面的数据
    videoLink = scrapy.Field()
    title = scrapy.Field()
    # pass

设置好items文件后需要在爬虫文件(stsp.py)头部添加如下代码:

from st.items import StItem # 这个要设置根目录文件即st

然后调整stsp文件:

item = StItem(videoLink=videoLink,title=title)yield item # 这里必须使用yield,如果使用return最后在管道中只能得到一个文件

piplines:

# 前面的注释代码
from itemadapter import ItemAdapter
import csv

class StPipeline:
    def __init__(self):
        # 打开文件,指定方式为写,利用第3个参数把csv写数据时产生的空行消除
        self.f = open('Sp.csv','w',encoding='utf-8',newline='')
        # 设置文件第一行的字段名,注意要跟spider传过来的字典key名称相同
        self.file_name = ['title''videoLink']
        # 指定文件的写入方式为csv字典写入,参数1为指定具体文件,参数2为指定字段名
        self.writer = csv.DictWriter(self.f, fieldnames=self.file_name)
        # 写入第一行字段名,因为只要写入一次,所以文件放在__init__里面
        self.writer.writeheader()

    def process_item(self, item, spider):
        # 写入spider传过来的具体数值
        self.writer.writerow(dict(item)) # 这里的item是上面创建出来的实例对象,需要转换成dict
        # 写入完返回
        return item

    def close_spider(self,spider):
        self.f.close()

四、批量爬取

next_url = 'https://699pic.com/video-sousuo-0-18-0-0-0-{}-4-popular-0-0-0-0-0-0.html'.format(count) # 这里的count是初始化的全局变量count,每次执行数据解析,就让他+1
request = scrapy.Request(next_url)
yield request

最后运行程序:

csv文件:

page2.mp4文件:

-End-

最近有一些小伙伴,让我帮忙找一些 面试题 资料,于是我翻遍了收藏的 5T 资料后,汇总整理出来,可以说是程序员面试必备!所有资料都整理到网盘了,欢迎下载!

点击👆卡片,关注后回复【面试题】即可获取

在看点这里好文分享给更多人↓↓

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/118682
 
452 次点击