当前位置: 首页 > 科技观察

如何用Python+Scrapy爬取视频?

时间:2023-03-14 21:38:11 科技观察

本文转载自微信公众号《快学Python》,作者快。转载本文请联系速学Python公众号。人生苦短,赶快学好Python!今天就带大家简单了解一下Scrapy爬虫框架,并用一个真实的案例来演示代码编写和爬取的过程。一、scrapy简介1、什么是Scrapy?Scrapy是一个为爬取网站数据和提取结构化数据而编写的应用程序框架。我们只需要实现少量代码就可以快速爬取Scrapy。使用Twisted异步网络框架,可以加快我们的下载速度http://scrapy-chs.readthedocs.io/zh_CN/1.0/intro/overview.html异步和非阻塞的区别异步:调用之后是发出,调用直接返回,不管有没有结果阻塞:关注的是程序等待调用结果时的状态,也就是说调用不会阻塞当前线程,直到2.Scrapyworkflow另一种爬取方式ScrapyworkflowScrapyengine(引擎)Commander:负责不同模块之间数据和信号的传递scrapy实现了一个Scheduler(调度器)一个队列,用于存储Scrapy发送的请求引擎。scrapy实现了Downloader(下载器),下载引擎发送的请求,返回给引擎Scrapy实现了Spider(爬虫),处理引擎发送的response,提取数据,提取url,交给引擎.ItemPipeline(管道)是处理引擎传输的数据所必需的。比如存储需要手写DownloaderMiddlewares(下载中间件)。自定义下载扩展,比如设置代理,一般不需要手写SpiderMiddlewares(中间件),可以自定义requests和process响应过滤一般不需要手写3.Scrapy入门#1创建一个scrapy项目scrapystartprojectmySpider#2生成一个爬虫scrapygenspiderdemo"demo.cn"#3提取数据和改进spider使用xpath等#4管道中保存数据运行爬虫的命令中保存数据scrapycrawlqb#qb爬虫名称在pycharm中运行爬虫fromscrapyimportcmdlinecmdline.execute("scrapycrawlqb".split())4.使用管道从字典形状的pipeline,我们可以看到可以有多个pipeline,确实pipeline可以定义多个whyit需要多个pipeline:1.spider可能有多个,不同的pipeline处理不同的item内容。2.一个蜘蛛的内容可以进行不同的操作,比如存储在不同的数据库中。注意:1.pipeline的权重越小,优先级越低pipeline中的process_item方法名越高不能改成别的名字5.文件目录结构文件配置:setting:SPIDER_MODULES=['st.spiders']NEWSPIDER_MODULE='st.spiders'LOG_LEVEL='WARNING'#这个设置可以在Donotprintlogfileswhenrunning...#Obeyrobots.txtrulesROBOTSTXT_OBEY=False#调整为false,...#Overridethedefaultrequestheaders:#Header信息,反-crawlDEFAULT_REQUEST_HEADERS={'user-agent':'Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/88.0.4324.96Safari/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同目录),从scrapyimportcmdlinecmdline.execute('scrapycrawlstsp'.split())#这里的爬虫项目名称是stsp,目前是这样的,后面提取数据的时候会修改对应的文件。二、页面分析第一页url:https://699pic.com/video-sousuo-0-18-0-0-0-1-4-popular-0-0-0-0-0-0.htmlurl规则:url='https://699pic.com/video-sousuo-0-18-0-0-0-{}-4-popular-0-0-0-0-0-0.html'.format(i)通过分析页面,我们知道视频数据在li中,如图。现在问题很简单3.解析数据defparse(self,response):#globalcount#count+=1#print(response)liList=response.xpath('//li')#获取所有li,然后提取有用的print(len(liList))#76(然后分析11到70就是我们需要的数据)newfolderName='page{}'.format(count)#文件夹名称page1,page2,....#Step2新建文件夹将视频保存在每个页面上).extract_first()videoLink='https:'+video_link#url拼接title=li.xpath("./a[2]/h3/text()").extract_first()#下载数据:res=requests.get(videoLink,headers=headers)data=res.contenttry:withopen(newfolderName+'/'+title+'.mp4','wb')asf:f.write(data)print('%s下载成功'%title)except:break四、文件配置项:importscrapyclassStItem(scrapy.Item):#definethefieldsforyouritemherelike:#和前面数据对应的两个videoLink=scrapy.Field()title=scrapy.Field()#pass设置items文件后需要在爬虫文件(stsp.py)头部加入如下代码:fromst.itemsimportStItem#这里是设置根目录文件,也就是st,然后调整stsp文件:item=StItem(videoLink=videoLink,title=title)yielditem#这里必须使用yield,如果使用returnmost最后在pipeline中只能得到一个文件:#前面的注释代码fromitemadapterimportItemAdapterimportcsvclassStPipeline:def__init__(self):#打开文件,指定写入方法,使用第三个参数消除csv写入数据时产生的空行self.f=open('Sp.csv','w',encoding='utf-8',newline='')#设置文件第一行的字段名,注意和字典一样蜘蛛传递的keynameself.file_name=['title','videoLink']#指定文件的写入方式为csv字典写入,参数1为指定具体文件,参数2为指定字段名self.writer=csv.DictWriter(self.f,fieldnames=self.file_name)#写第一行的字段名,因为只需要写一次,所以文件放在__init__self.writer.writeheader()defprocess_item(self,item,spider):#写入蜘蛛传过来的具体值self.writer.writerow(dict(item))#这里的item就是上面创建的实例对象,需要转换成dict#写入后返回itemdefclose_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。每次进行数据分析,让他+1request=scrapy.Request(next_url)yieldrequest最后运行程序:csv文件:page2.mp4文件: