美文网首页Python程序员联盟@IT·互联网安卓
Python3爬取百科词条+导入MySQL数据库

Python3爬取百科词条+导入MySQL数据库

作者: 丶legend | 来源:发表于2017-06-21 00:38 被阅读84次

    本文主要介绍使用Python爬虫爬取Python百度词条的信息 主要参考慕课网的《开发简单爬虫》以及一些数据库操作

    开发工具

    ---工欲善其事 必先利其器

    首先 这里开发工具用的Python3.6+Pycharm+MySQL5.7+SQLyog
    前面2个的安装直接网上搜下教程一大堆 而且免去了配置环境变量的操作,MySQL数据库(安装教程也一大堆)现在最新版是5.7 它的安装与之前的有点不同


    Python3爬取百科词条+导入MySQL数据库

    注意到没 安装时多了一个必须选项 安装InnoDB时设置password 然后再填入即可 其它步骤和一般软件没什么区别
    然后去搜索引擎下载SQLyog工具(用Pycharm自带的dataBase应该也可以 有兴趣的小伙伴可以去试试 ) 连接数据库


    Python3爬取百科词条+导入MySQL数据库

    点击连接 出错的可以看看 进入控制面板→管理工具→服务→看MySQL service是否打开 连接好后创建数据库baikeurl 然后建url表

    再建立4个栏位 分别是 id urlname urlhref urlcontent Python3爬取百科词条+导入MySQL数据库

    爬虫的架构及具体流程

    1.传入目标url后调用URL管理器
    2.URL管理器对URL进行具体的判断与检索后传入网页下载器
    3.网页下载器工作后将网页传入网页解析器
    4.将解析后的内容(url,title,content等)传入输出器
    5.最后输出器进行数据操作(写入文件 导入数据库等)
    整个过程采用了严格的面向对象思想 每一过程具体的函数都封装在相应文件中


    Python3爬取百科词条+导入MySQL数据库 Python3爬取百科词条+导入MySQL数据库

    实例分析

    要爬取的链接:http://baike.baidu.com/item/Python
    通过浏览器的开发者工具分析可知 百度百科的词条
    链接:/item/……的形式
    标题: <dd class="lemmaWgt-lemmaTitle-title"><h1>……</h1> 内容:<div class="lemma-summary">……</div>

    废话不多说 直接上代码 关键地方带注释 一个包括5个文件

    爬虫调度端(主页)

    spider.py文件

    import html_downloader
    import html_outputer
    import html_parser
    import url_manager
    
    #爬虫主函数
    class SpiderMain(object):
        def __init__(self):
            self.urls = url_manager.UrlManager()
            self.downloader = html_downloader.HtmlDownloader()
            self.parser = html_parser.HtmlParser()
            self.outputer = html_outputer.HtmlOutputer()
    #抓取过程函数
        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.collect_data(new_data)
                    if count == 1000:
                        break
                    count = count+1
                except:
                    print('craw failed')
    
            self.outputer.into_mysql()
    if __name__ == '__main__':
        rooturl = 'http://baike.baidu.com/item/Python'
        obj_spider = SpiderMain()
        obj_spider.craw(rooturl)
    

    url管理器
    url_manager.py文件

    # -*- coding: utf-8 -*-
    class UrlManager(object):
        def __init__(self):
            self.new_urls = set()
            self.old_urls = set()
        def add_new_url(self, root_url):
            if root_url is None:
                return
            if root_url not in self.new_urls and root_url not in self.old_urls:
                self.new_urls.add(root_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
        def add_new_urls(self, new_urls):
            if new_urls is None or len(new_urls) == 0:
                return
            for url in new_urls:
                self.add_new_url(url)
    

    网页下载器
    html_downloader.py文件

    import urllib.request
    class HtmlDownloader(object):
        def download(self, new_url):
            if new_url is None:
                return None
            response =  urllib.request.urlopen(new_url)
            if response.getcode() != 200:
                return None
            return response.read()
    

    网页解析器
    html_parse.py文件

    import re
    import urllib
    from urllib import parse
    
    from bs4 import BeautifulSoup
    
    class HtmlParser(object):
        def parse(self, new_url, html_cont):
            if new_url is None or html_cont is None:
                return
            soup = BeautifulSoup(html_cont,'html.parser'    )
            new_urls = self._get_new_urls(new_url,soup)
            new_data = self._get_new_data(new_url,soup)
            return new_urls,new_data
    
        def _get_new_urls(self, new_url, soup):
            new_urls = set()
    #获取要爬取的链接
            links = soup.find_all('a',href=re.compile(r'/item/\w+'))
            for link in links:
                new_url1 = link['href']
                new_full_url = parse.urljoin(new_url, new_url1)
                new_urls.add(new_full_url)
            return new_urls
        def _get_new_data(self, new_url, soup):
            res_data = {}
            res_data['url'] = new_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()
    #获取词条的内容
            summary_node = soup.find('div',class_='lemma-summary')
            res_data['summary'] = summary_node.get_text()
            return res_data
    

    输出器

    html_outputer.py文件

    class HtmlOutputer(object):
        def __init__(self):
            self.datas = []
        def collect_data(self, new_data):
            if new_data is None:
                return
            print(new_data['summary'])
            self.datas.append(new_data)
    #数据库操作函数
        def into_mysql(self):
            i = 0
            for data in self.datas:
                conn = pymysql.Connect(
                    host='127.0.0.1',
                    user='你的用户名',
                    password='你的密码',
                    db='数据库名称',
                    port=3306,
                    charset='utf8mb4'
                )
                try:
                    cursor = conn.cursor()
                    i += 1
                    sql = 'insert into `urls`(`id`,`urlname`,`urlhref`,`urlcontent`)values(%s,%s,%s,%s)'
    #执行上面的sql语句 并传入4个参数
    #分别是id,title,url,content
                    cursor.execute(sql, (i, data['title'],data['url'],data['summary']))
                    conn.commit()
                finally:
    
                    conn.close()
    

    注:关于编码问题 因为该网页就是采用的utf-8编码 所以无需调用encode()方法编码 直接data['summary']的内容就是正常显示 若将数据写入文件 则需要第二个参数传入encoding='' 指定文件编码方式 测试时尽量不用Windows系统自带的IE浏览器 由于默认编码问题 会导致显示乱码(当时就是被这个问题困扰) 换用记事本或其它浏览器就正常显示了
    最后点击运行

    Python3爬取百科词条+导入MySQL数据库
    运行 爬取网页正常 然后我们去看看数据库
    Python3爬取百科词条+导入MySQL数据库
    数据库也导入成功了 到此 我们的需求就完成了 最后附上github地址

    相关文章

      网友评论

        本文标题:Python3爬取百科词条+导入MySQL数据库

        本文链接:https://www.haomeiwen.com/subject/snraqxtx.html