zoukankan      html  css  js  c++  java
  • 百度百科词条内容爬取-爬虫大作业

    实现过程

    一、前期准备

    首先打开要爬取的页面,作为根源页面。

    我这里使用的百度百科的PHP词条,网址为https://baike.baidu.com/item/PHP/9337?fr=aladdin&fromid=6717846&fromtitle=%EF%BC%B0%EF%BC%A8%EF%BC%B0

    然后选取其中适合收集信息的文字内容,右键审查。

    可以发现该词条内关联的词条(url)非常多

    装好软件和相关第三方库,开搞♂。

    环境如下:

      python3.6.2    PyCharm

      Windows10    第三方库(jieba,wordcloud,bs4,Requests,re)

    二、写代码

    爬虫的架构大致如下

    第一步先写个main来做调度,列好要实现的功能。

        def __init__(self):
            self.urls=url_manager.UrlManager() #url管理器
            self.downloader=html_downloader.HtmlDownloader()#下载器
            self.parser=html_parser.HtmlParser()#解析
            self.outputer=html_outputer.HtmlOutouter()#输出
    

      然后写

        def craw(self,root_url):
            count=1
            self.urls.add_new_url(root_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.collest_data(new_data)
                    if count>500:
                        break
    
                    count+=1
    
                except Exception as e:
                    print(str(e))
    
                self.outputer.output_html()
    
    
    
    if __name__=="__main__":
        root_url='https://baike.baidu.com/item/PHP/9337?fr=aladdin&fromid=6717846&fromtitle=%EF%BC%B0%EF%BC%A8%EF%BC%B0'
        obj_spider=SpiderMain()
        obj_spider.craw(root_url)
    

      url管理器

    class UrlManager(object):
        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 in self.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.add_new_url(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
    

      接下来写下载器

    class HtmlDownloader(object):
        def download(self,url):
            if url is None:
                return None
    
            url_ =quote(url,safe=string.printable)
            response =request.urlopen(url_)
    
            if response.getcode()!=200:
                return None
    
            return response.read()
    

      解析器来一个,百度百科链接的规律是baike.baidu.com/item/*

    from bs4 import  BeautifulSoup
    import re
    import urllib.parse
    class HtmlParser(object):
        def _get_new_urls(self, page_url, soup):
            new_urls = set()
            links=soup.find_all('a',href=re.compile(r"/item/"))
    
            for link in links:
                new_url = link['href']
                new_full_url=urllib.parse.urljoin(page_url,new_url)
                new_urls.add(new_full_url)
            return new_urls
    
        def _get_new_data(self, page_url, soup):
            res_data = {}
    
            # url
            res_data['url'] = page_url
    
            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')
            if summary_node is None:
                return
            res_data['summary'] = summary_node.get_text()
    
            #<div class="para" label-module="para">
            para_node = soup.find('div', class_='para')
            if para_node is None:
                return
            res_data['para'] = para_node.get_text()
    
            return res_data
    
        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
    

      输出到一个叫output.txt的文件

    # -*- coding: UTF-8 -*-
    class HtmlOutouter(object):
        def __init__(self):
            self.datas=[]
    
        def collest_data(self, new_data):
            if new_data is None:
                return
            self.datas.append(new_data)
    
        def output_html(self):
            fout=open('output.txt','w',encoding='utf-8')
    
    
            for data in self.datas:
    
                fout.write('%s' % ( data['title']))
                fout.write('%s' % data['para'])
                fout.write('%s' % data['summary'])
    
    
            fout.close()
    

      

    得到txt文件一个

    里面有爬了五百个url搞到手的文字内容。

    三、生成词云

    装词云库时有点小麻烦,下面再说。

    #通过jieba分词进行分词并通过空格分隔
    wordlist_after_jieba = jieba.cut(text_from_file_with_apath, cut_all = True)
    wl_space_split = " ".join(wordlist_after_jieba)
    #my_wordcloud = WordCloud().generate(wl_space_split) 默认构造函数
    my_wordcloud = WordCloud(
                background_color='white',    # 设置背景颜色
                mask = abel_mask,        # 设置背景图片
                max_words = 800,            # 设置最大现实的字数
                stopwords = {}.fromkeys(['以及', '就是','可以','简称','位于','称为','之一','包括','一种','主要']),        # 设置停用词
                font_path = 'C:/Users/Windows/fonts/simkai.ttf',# 设置字体格式,如不设置显示不了中文
                max_font_size = 50,            # 设置字体最大值
                random_state = 30,            # 设置有多少种随机生成状态,即有多少种配色方案
                    scale=.5
                    ).generate(wl_space_split)
    
    # 根据图片生成词云颜色
    image_colors = ImageColorGenerator(abel_mask)
    

      调用,运行

    背景图为

    生成的词云图为

    完成

    遇到的问题及解决办法

    1.word cloud安装失败,根据错误报告提示缺少vs c++构建工具。通过安装一个vs2017解决

    2.一开始是打算爬百度贴吧的,但是爬百度贴吧的时候IP被拉黑了。本来打算通过动态IP的方式,但是没成功。所以去爬百度百科了。

    3.词云生成的图片过于模糊,文字看不清楚。多次尝试发现跟原图的分辨率有关,换张分辨率高的图片获得不错的效果。

    4.词云中无意义的词(如连接词等)太多。没搞到常用stopwords文件(csdn要三个积分),只能手动加了几个无意义的过滤词。

    5.Windows10的字体文件格式是TTC,兼容TTF,使用ttf字体文件有一定概率失常。

    6.尽量使用纯白色背景的图片来当背景图,不然根本看不出轮廓。

    7.url,class后面要加_,不然一堆报错。

    总结

    写这个爬虫的时候暴露出了我的python基础很不好,需要再学好python。

    爬虫是很有趣的东西,我会继续去学习更深入、更厉害的知识技能。

  • 相关阅读:
    python基础-第十二篇-12.1jQuery基础与实例
    python基础-第十一篇-11.2DOM为文档操作
    [LC] 170. Two Sum III
    [Algo] 11. Rainbow Sort
    [LC] 31. Next Permutation
    [LC] 994. Rotting Oranges
    [LC] 863. All Nodes Distance K in Binary Tree
    [Algo] 132. Deep Copy Undirected Graph
    [LC] 138. Deep Copy Linked List With Random Pointer
    [Algo] 118. Array Deduplication IV
  • 原文地址:https://www.cnblogs.com/jiesheng/p/8901703.html
Copyright © 2011-2022 走看看