imooc疯狂的蚂蚁《Python开发简单爬虫》源代码

来源:互联网 发布:tracert端口号 编辑:程序博客网 时间:2024/06/06 04:31

以下为imooc疯狂的蚂蚁《Python开发简单爬虫》源代码,调试有些问题。

html_downloader.py

import html_downloaderimport html_outputimport html_parserimport url_managerimport tracebackclass SpiderMain:    def __init__(self):        #初始化所需的对象,包括url管理器,网页下载器,网页解析器,输出器提供给craw()使用        self.urls=url_manager.UrlManager()        self.downloader=html_downloader.HtmlDownloader()        self.parser=html_parser.HtmlParser()        self.outputer=html_output.HtmlOutputer()    def craw(self,url):        #一个计数        count=1        #添加根url        self.urls.add_new_url(url)        #开始解析        while self.urls.has_new_url():            try:                #获取url                new_url=self.urls.get_new_url()                print('第%d个url:%s'%(count,new_url))                #将该url的页面进行下载                html_cont=self.downloader.download(new_url)                #对下载的页面内容进行解析,存入两个变量中                new_urls,new_data= self.parser.parse(new_url,html_cont)                #将解析获得的新urls添加到url管理器中                self.urls.add_new_urls(new_urls)                #将数据进行收集                self.outputer.collect_data(new_data)                if count==1000:                    break                count+=1            except:                print('爬取失败')                traceback.print_exc()        #将收集的数据输出为一个html        self.outputer.output_html()if __name__=='__main__':    root_url='http://baike.baidu.com/view/21087.htm'    #root_url ='https://baike.baidu.com/item/Python/407313'    obj_spider=SpiderMain()    obj_spider.craw(root_url)

html_output.py

class HtmlOutputer(object):    #手机数据需要一个列表进行维护    def __init__(self):        self.datas=[]    def collect_data(self, new_data):        if new_data is None:            return        self.datas.append(new_data)    #输出一个html文档    def output_html(self):        fileout=open('output.html','w',encoding='utf-8')        fileout.write('<html>')        fileout.write('<head>')        fileout.write('<meta charset=\'utf-8\'>')        fileout.write('</head>')        fileout.write('<body>')        fileout.write('<table>')        for data in self.datas:            fileout.write('<tr>')            fileout.write('<td>%s</td>' % data['url'])            fileout.write('<td>%s</td>' % data['title'])            fileout.write('<td>%s</td>' % data['summary'])            fileout.write('</tr>')        fileout.write('</table>')        fileout.write('</body>')        fileout.write('</html>')        fileout.close()

html_parser.py

import reimport urllib.parsefrom bs4 import BeautifulSoupclass HtmlParser(object):    #对html_cont的内容进行解析    def parse(self, page_url, html_cont):        if page_url is None or html_cont is None:            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    #获取页面上所有的url    def _get_new_urls(self, page_url, soup):        new_urls=set()        #根据分析,链接的格式为:/view/12334.htm        #/item/%E9%98%BF%E5%A7%86%E6%96%AF%E7%89%B9%E4%B8%B9/2259975        links=soup.find_all('a',href=re.compile(r'/view/\d+\.htm'))        for link in links:            new_url=link['href']            #url格式需要进行拼接,加上http://baike.baidu.com            new_full_url=urllib.parse.urljoin(page_url,new_url)            new_urls.add(new_full_url)        return new_urls    #获取该页面的数据,包含url、标题、简介    def _get_new_data(self, page_url, soup):        #以一个词典类型保存数据        res_data={}        #保存url        res_data['url']=page_url        #下面是标题的格式        #<dd class="lemmaWgt-lemmaTitle-title"> <h1>Python</h1>        title_node=soup.find('dd',class_="lemmaWgt-lemmaTitle-title").find('h1')        res_data['title']=title_node.get_text()        #开始获取简介的内容        #<div class="lemma-summary" label-module="lemmaSummary">        summary_node=soup.find('div',class_="lemma-summary")        res_data['summary']=summary_node.get_text()        return res_data

spider_main.py

import html_downloaderimport html_outputimport html_parserimport url_managerimport tracebackclass SpiderMain:    def __init__(self):        #初始化所需的对象,包括url管理器,网页下载器,网页解析器,输出器提供给craw()使用        self.urls=url_manager.UrlManager()        self.downloader=html_downloader.HtmlDownloader()        self.parser=html_parser.HtmlParser()        self.outputer=html_output.HtmlOutputer()    def craw(self,url):        #一个计数        count=1        #添加根url        self.urls.add_new_url(url)        #开始解析        while self.urls.has_new_url():            try:                #获取url                new_url=self.urls.get_new_url()                print('第%d个url:%s'%(count,new_url))                #将该url的页面进行下载                html_cont=self.downloader.download(new_url)                #对下载的页面内容进行解析,存入两个变量中                new_urls,new_data= self.parser.parse(new_url,html_cont)                #将解析获得的新urls添加到url管理器中                self.urls.add_new_urls(new_urls)                #将数据进行收集                self.outputer.collect_data(new_data)                if count==1000:                    break                count+=1            except:                print('爬取失败')                traceback.print_exc()        #将收集的数据输出为一个html        self.outputer.output_html()if __name__=='__main__':    root_url='http://baike.baidu.com/view/21087.htm'    #root_url ='https://baike.baidu.com/item/Python/407313'    obj_spider=SpiderMain()    obj_spider.craw(root_url)

url_manager.py

class UrlManager(object):    def __init__(self):        self.new_urls=set()        self.old_urls=set()    #添加一个新的url    def add_new_url(self, url):        if url is None:            return        #当该url既不在新列表中也不在旧列表中,则添加到新列表中        if url not in self.new_urls and url not in self.old_urls:            self.new_urls.add(url)    #判断是否还有新的待爬去的url    def has_new_url(self):        return len(self.new_urls)!=0    #返回一个新的url,有出入操作    def get_new_url(self):        new_url=self.new_urls.pop()        self.old_urls.add(new_url)        return new_url    #添加一组新url    def add_new_urls(self, new_urls):        if new_urls is None or len(new_urls)==0:            return        for new_url in new_urls:            self.add_new_url(new_url)


原创粉丝点击