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

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

开发工具

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

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


图片发自简书App

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


图片发自简书App

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

再建立4个栏位 分别是 id urlname urlhref urlcontent
图片发自简书App

爬虫的架构及具体流程

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


图片发自简书App
图片发自简书App

实例分析

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

图片发自简书App

运行 爬取网页正常 然后我们去看看数据库
图片发自简书App

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,383评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,522评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,852评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,621评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,741评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,929评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,076评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,803评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,265评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,582评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,716评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,395评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,039评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,027评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,488评论 2 361
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,612评论 2 350

推荐阅读更多精彩内容