Python开发简单爬虫(二)

7.实战演练:爬取百度百科1000个页面的数据
1.爬虫实例—分析目标

       步骤:


确定目标:确定抓取哪个网站的哪个网页的哪些数据—百度百科python词条页面以及相关词条页面的标题和简介

分析目标:确定抓取策略:url格式限定抓取范围  分析数据格式:分析标题和简介的格式  网页的编码

编写代码:

执行爬虫:进行数据的抓取

 

1.打开百度百科的页面:确定url,然后点击链接,查看相关词条的url格式,(右键审查元素)

总结:

1.目标:百度百科Python词条相关词条网页—标题和简介

2.入口页:

http://baike.baidu.com/view/21087.htm

3.url格式:词条页面url:/view/125370.html(在任意一个链接上右键审查元素),这不是一个完整的URL.需要在之前补上/baike.baidu.com

4.数据格式:(分别在标题和简介上右键审查元素)

       —标题:<dd class=”lemmaWgt-lemmaTitle-title”><h1>****</h1></dd>

       —简介:<div class=”lemma_summary”>***</div>

5.页面编码:UTF-8(再页面任意位置审查元素,head标签中有编码格式)

注意:每一个互联网的网站都会不停的升级它的格式,所以定向爬虫也要相应的升级

 

2.调度程序(关键)

       编写爬取百度百科Python词条相关1000个页面数据

1)包和模块的创建:

       包:baike_spider

       模块:spider_main.py  程序的入口文件

                url_manager.py  url管理器

                html_downloader.py  下载器

              html_parser.py  解析器

              html_outputer.py  结果收集和输出

2)编写爬虫入口程序:自顶向下的方式

       if__name__==”__main__”:

              root_url=http://baike.baidu.com/view/21087.htm

              obj_spider=SpiderMain()#创建一个spider对象

              obj_spider.craw()#开始爬虫

在spider中进行管理器,下载器和解释器以及结果的展示的初始化

在craw中进行爬虫的过程执行:首先把root_url加入new_url列表,然后开始执行爬重循环,只要has_new_url()不为空:首先get_new_url(),然后downloader.download(new_url),然后将获取的html_cont传给parser.parse(),返回new_urls和new_data,并将new_urls加入new_url列表,将new_data存入outputer.collect_data()

 

最后,将outputer.output_html将结果输出

#coding:utf-8

'''

Created on 2015-12-29

爬虫的总调度程序入口

@author: Administrator

'''

frombaike_spider importurl_manager, html_downloader, html_parser,\

   html_outputer

 

 

class SpiderMain(object):

   def __init__(self):#初始化url管理器,下载器,解释器和输出器

        self.urls=url_manager.UrlManger()

        self.downloader=html_downloader.HtmlDownloader()

        self.parser=html_parser.HtmlParser()

        self.outputer=html_outputer.HtmlOutputer()

       

   

   def craw(self,root_url):

        count=1  #记录当前爬取的是第几个url

        self.urls.add_new_url(root_url)#首先将入口url添加进url管理器

        while self.urls.has_new_url():#开始启动爬虫的循环

            try:

                new_url=self.urls.get_new_url()

                print 'craw %d : %s'%(count,new_url)

                html_cont=self.downloader.download(new_url)

                new_urls, new_data= self.parser.parse(new_url,html_cont)

                self.urls.add_new_urls(new_urls)

                self.outputer.collect_data(new_data)

               

                if count==5:

                    break

               

                count=count+1

            except:

                print 'craw failed %s' %new_url

        self.outputer.output_html()

if__name__=='__main__':

   root_url="http://baike.baidu.com/view/21087.htm"#设置爬虫的入口url

   obj_spider=SpiderMain()#创建一个spider

   obj_spider.craw(root_url)#启动爬虫

 

3.URL管理器

       管理两个列表:new_urls ,old_urls

       添加new_url ,添加old_urls

       判断是否还有new_url ,获取new_url

#coding:utf-8

'''

Created on 2015-12-29

 

@author: Administrator

'''

 

 

class UrlManger(object):#需要维护两个列表,一个是待爬取的url 一个是已经爬取过的url

    def __init__(self):

        self.new_urls=set()

        self.old_urls=set()

   

    def add_new_url(self,url):

        if url is None:

            return

        if url not in self.new_urls and url not inself.old_urls:

            self.new_urls.add(url)

 

    def add_new_urls(self,urls):

        if urls is None or len(urls)==0:

            return

        for url in urls:

            self.new_urls.add(url)

 

    def has_new_url(self):

        return len(self.new_urls)!=0

   

    def get_new_url(self):

        new_url=self.new_urls.pop()

        self.old_urls.add(new_url)

        return new_url

 

4.HTML下载器html_downloader

       通过urllib2模块对url下载

#coding:utf-8

'''

Created on 2015-12-29

@author: Administrator

'''

import urllib2

 

class HtmlDownloader(object):

   

   

    def download(self,url):

        if url is None:

            return None

       

        response=urllib2.urlopen(url) 

       

        if response.getcode()!=200:

            return None

       

        return response.read()

 

5.HTML解析器html_parser

       对 html_cont进行解析,调用BeautifulSoup模块,进行解析出新的new_urls和new_data,注意此时解析的url不是完整的url需要进行补全

 

#coding:utf-8

'''

Created on 2015-12-29

 

@author: Administrator

'''

from bs4 import BeautifulSoup

import re

import urlparse

 

class HtmlParser(object):

 

    def _get_new_urls(self, page_url, soup):

        new_urls=set()

        links=soup.find_all('a',href=re.compile(r"/view/\d+\.htm"))

        for link in links:

            new_url=link['href']

           new_full_url=urlparse.urljoin(page_url,new_url)

            new_urls.add(new_full_url)

    

        return new_urls

   

    def _get_new_data(self, page_url,soup):

        res_data={}

        res_data['url']=page_url

        title_node=soup.find('dd',{"class":"lemmaWgt-lemmaTitle-title"}).find('h1')

        res_data['title']=title_node.get_text()

        summary_node=soup.find('div',{"class":"lemma-summary"})

        res_data['summary']=summary_node.get_text()

       

        return res_data

       

   

   

   

    def parse(self,page_url,html_cont):

        if page_url is None or html_contisNone:

            return

 

        soup=BeautifulSoup(html_cont,'html.parser',from_encoding='utf-8')

       

        new_urls=self._get_new_urls(page_url,soup)

        new_data=self._get_new_data(page_url,soup)

 

        return new_urls,new_data   

6.HTML输出器html_outputer

       需要将数据写入output.html文件,并且没有的话就创建

    维护一个datas的列表,来源为collect_data()函数,输出以表格的形式输出

#coding:utf-8

'''

Created on 2015-12-29

 

@author: Administrator

'''

 

class HtmlOutputer(object):

   

    def __init__(self):

        self.datas=[]

    def collect_data(self,data):

        if data is None:

            return

        self.datas.append(data)

 

    def output_html(self):

        fout=open('output.html','w')

        fout.write("<html>")

        fout.write("<head>")

        fout.write("<meta http-equiv='Content-Type' content='text/html;charset=utf-8' />")

        fout.write("</head>")

        fout.write("<body>")

        fout.write("<table border='1',cellspacing='0',color='red'>")

       

        i=0

        for data in self.datas:

            if i%2==0:

                color="#00FFFF"

            else:

                color="#00DDDD"

            fout.write("<tr Bgcolor=%s>" %color)

            fout.write("<td> %s </td>" % data['url'])

            fout.write("<td> %s </td>" % data['title'].encode('utf-8'))

            fout.write("<td> %s </td>" % data['summary'].encode('utf-8'))

            fout.write("</tr>")

            color=color+"#000002"

            i=i+1

        fout.write("</table>")

        fout.write("</body>")

        fout.write("</html>")

        fout.close()

 

7.开始运行爬虫和爬取结果展示

       执行spider_main.py就可以咯

非常抱歉,我在给出的代码中错误地提及了 `VirtualCamera` 类。事实上,SharpDX.MediaFoundation 库本身并没有提供直接创建虚拟摄像头的功能。要创建虚拟摄像头并将视频流推送到它,你可能需要使用第三方库或工具,例如虚拟摄像头驱动程序或框架。 一种常见的选择是使用 Dshow 系统库。你可以使用 DirectShow 库来创建虚拟摄像头,并使用 SharpDX.MediaFoundation 与 DirectShow 进行交互。以下是一个基本的示例代码,演示了如何将视频流推送到虚拟摄像头: ```csharp using System; using DirectShowLib; using SharpDX.MediaFoundation; class Program { static void Main() { // 加载虚拟摄像头驱动程序 var virtualCamera = LoadVirtualCameraDriver(); if (virtualCamera == null) { Console.WriteLine("无法加载虚拟摄像头驱动程序!"); return; } // 创建源视频文件的读取器 using (var sourceReader = CreateSourceReader("path/to/source/video.mp4")) { // 获取第一个视频流的格式 var mediaType = GetVideoMediaType(sourceReader, 0); // 将视频流推送到虚拟摄像头 PushVideoToVirtualCamera(sourceReader, virtualCamera, mediaType); Console.WriteLine("视频流已成功推送到虚拟摄像头!按任意键停止..."); Console.ReadKey(); } // 卸载虚拟摄像头驱动程序 UnloadVirtualCameraDriver(virtualCamera); } static IBaseFilter LoadVirtualCameraDriver() { // TODO: 加载虚拟摄像头驱动程序的代码 // 可以使用 DirectShowLib 库中的 FilterGraph 或其他相关类来加载虚拟摄像头驱动程序并获取其 IBaseFilter 对象 return null; } static void UnloadVirtualCameraDriver(IBaseFilter virtualCamera) { // TODO: 卸载虚拟摄像头驱动程序的代码 // 可以使用 DirectShowLib 库中的 FilterGraph 或其他相关类来卸载虚拟摄像头驱动程序 } static SourceReader CreateSourceReader(string videoFilePath) { var attributes = new MediaAttributes(); attributes.Set(CaptureDeviceAttributeKeys.SourceType, CaptureDeviceAttributeKeys.SourceTypeVideoCapture.Guid); var sourceReader = new SourceReader(videoFilePath, attributes); return sourceReader; } static MediaType GetVideoMediaType(SourceReader sourceReader, int streamIndex) { var mediaType = sourceReader.GetNativeMediaType(streamIndex, 0); return mediaType; } static void PushVideoToVirtualCamera(SourceReader sourceReader, IBaseFilter virtualCamera, MediaType mediaType) { var sample = new MediaSample(); // TODO: 将视频流推送到虚拟摄像头的代码 // 可以使用 DirectShowLib 库中的 FilterGraph 或其他相关类来将视频流推送到虚拟摄像头 } } ``` 注意,上述代码中的 `LoadVirtualCameraDriver` 和 `UnloadVirtualCameraDriver` 方法是示例代码,需要根据你使用的虚拟摄像头驱动程序进行实际实现。你可以使用 DirectShowLib 库中的 FilterGraph 类或其他相关类来加载和卸载虚拟摄像头驱动程序。 希望这次提供的代码能够帮助到你,如果你有任何进一步的问题随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值