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

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

开发工具

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

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


Python3爬取百科词条+导入MySQL数据库_第1张图片
图片发自App

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


Python3爬取百科词条+导入MySQL数据库_第2张图片
图片发自App

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

再建立4个栏位 分别是 id urlname urlhref urlcontent
Python3爬取百科词条+导入MySQL数据库_第3张图片
图片发自App

爬虫的架构及具体流程

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


Python3爬取百科词条+导入MySQL数据库_第4张图片
图片发自App
Python3爬取百科词条+导入MySQL数据库_第5张图片
图片发自App

实例分析

要爬取的链接:http://baike.baidu.com/item/Python
通过浏览器的开发者工具分析可知 百度百科的词条
链接:/item/……的形式
标题:

……

内容:
……

废话不多说 直接上代码 关键地方带注释 一个包括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
#

Python

#获取词条的标题 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浏览器 由于默认编码问题 会导致显示乱码(当时就是被这个问题困扰) 换用记事本或其它浏览器就正常显示了
最后点击运行

图片发自App

运行 爬取网页正常 然后我们去看看数据库
Python3爬取百科词条+导入MySQL数据库_第6张图片
图片发自App

数据库也导入成功了 到此 我们的需求就完成了 最后附上 github地址

你可能感兴趣的:(Python3爬取百科词条+导入MySQL数据库)