python3爬虫爬取英语单词到MySQL数据库

前言:我的第一篇博客,本人大一菜鸟一枚,第一次写python的项目,需要大量的数据,第一次接触爬虫这个东西,感觉十分有趣,想以后往这方面发展,特写下自己的爬虫学习经历,希望把自己的学习经历分享给初学者们,也希望各位大佬帮助指正。声明:没有使用多线程,没有使用代理IP,没有使用框架,最简单的一个爬虫爬到死

python版本:python3.6

使用requests库爬取,使用beautifulsoup库解析(使用了一点点正则表达式)

爬取的网页:http://word.iciba.com/


爬取目标:网站上所有的单词,单词的发音,单词的中文意思

首先分析网页找到我们要爬取的超链接:


经过我们分析后发现:





所有超链接只是后面的“classid=”这个东西在变,所以第一步找出所有的“classid”的数值:

def get_url(html):#解析首页得到所有的网址
    word_all = []#所有classid可能取值的列表
    mess = BeautifulSoup(html,'lxml')
    word_num = mess.select('.main_l li')
    for word in word_num:
        word_all.append(word.get('class_id'))
    return word_all

但我们发现单词并不在这一层,而在更里面一层


通过观察我们发现他只不过是在网址后面里加入了“course=”,进一步分析发现有多少课时course的数值就是1到~,所以我们按照上述方法得到course的所有取值

    for num in word_all:#word_all为classid所有可能的取值
        url_home = 'http://word.iciba.com/?action=courses&classid=' + str(num)#利用字符串拼接起来,得到URL网址
        html = get_urlhtml(url_home)
        mess = BeautifulSoup(html, 'lxml')
        li = mess.select('ul li')#解析得到所有的课时,其中li的长度就是课时的数量

通过一个双重循环得到每一个存在单词的网页:

for num in word_all:#word_all为classid所有可能的取值
    url_home = 'http://word.iciba.com/?action=courses&classid=' + str(num)#利用字符串拼接起来,得到URL网址
    html = get_urlhtml(url_home)
    mess = BeautifulSoup(html, 'lxml')
    li = mess.select('ul li')#解析得到所有的课时,其中li的长度就是课时的数量
    for j in range(1, len(li) + 1):#利用课时的数量就是course的取值的特性,得到course的取值
        url = 'http://word.iciba.com/?action=words&class=' + str(num) + '&course=' + str(j)#得到单词所在的URL网站

通过我们的解析函数得到我们想要的内容:

def paqu_wangye(reponse,name):#爬取所有的单词、发音、翻译
    word_mause={}
    mess = BeautifulSoup(reponse,'lxml')
    word = mess.find_all('div',class_="word_main_list_w")
    mause = mess.find_all(class_="word_main_list_y")
    fanyi = mess.find_all(class_='word_main_list_s')
    for i in range(1,len(word)):
        key = word[i].span.get('title')
        f = mause[i].strong.string.split()
        y = fanyi[i].span.get('title')
        if len(f) == 0:#因为某些发音不存在,我们直接放弃,不存入
            continue
        word_mause[key]=[f[0],y,name]
    print('创建数据成功')
    return word_mause

接下来最重要的就是存入数据库了:

首先我们先创建一个表用来存放所有的数据

def creat_table():#创建一个表
    db = pymysql.connect(host='localhost', user='root', password='zcj123.abc', db='123', port=3306)#打开数据库,尤其是密码和数据库一定不能打错
    print('打开数据库成功')
    cursor = db.cursor()#创建一个游标
    sql = 'CREATE TABLE IF NOT EXISTS word (id VARCHAR(255) NOT NULL,fayin VARCHAR(255) NOT NULL,fanyi VARCHAR(255) NOT NULL,music VARCHAR(255) NOT NULL,word_tream VARCHAR(255) NOT NULL, PRIMARY KEY (id))'#sql语句
    cursor.execute(sql)#创建
    print('创建表成功')
    db.close()

接下来就是将数据存入了:

def cucun(word_mause):#将数据存到数据库
    db = pymysql.connect(host='localhost', user='root', password='zcj123.abc', db='123', port=3306)#打开数据库
    print('打开数据库成功')
    cursor = db.cursor()#创建一个游标
    for key in word_mause:#word_mause是一个字典,模型:{'comment': ['[ˈkɔment]', 'n. 评论,意见;体现,写照', '四级必备词汇']}
        sql = 'INSERT INTO word(id, fayin, fanyi, music, word_tream) values(%s, %s, %s, %s, %s)'#构造sql语句
        try:
            cursor.execute(sql, (key,word_mause[key][0],word_mause[key][1],'music/'+key+'.mp3',word_mause[key][2]))
            db.commit()#插入数据
        except:
            db.rollback()#如果发生异常,则回滚(什么事情都没有发生)
    print('数据插入成功')
    db.close()#关闭数据库,记得一定要记得关闭数据库
    print('数据库成功关闭')

下面是整体的代码(内置爬取单词音频的代码,不过爬取效率不高):

import requests
from bs4 import BeautifulSoup
import pymysql
import re

header = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 UBrowser/6.1.2107.204 Safari/537.36'
}

def get_urlhtml(url):#爬取主页
    try:
        html = requests.get(url,headers = header)#使用requests库爬取
        if html.status_code == 200:#如果状态码是200,则表示爬取成功
            print(url+'解析成功')
            return html.text#返回H5代码
        else:#否则返回空
            print('解析失败')
            return None
    except:#发生异常返回空
        print('解析失败')
        return None

def get_url(html):#解析首页得到所有的网址
    word_all = []#所有classid可能取值的列表
    mess = BeautifulSoup(html,'lxml')
    word_num = mess.select('.main_l li')
    for word in word_num:
        word_all.append(word.get('class_id'))
    return word_all

def paqu_wangye(reponse,name):#爬取所有的单词、发音、翻译
    word_mause={}
    mess = BeautifulSoup(reponse,'lxml')
    word = mess.find_all('div',class_="word_main_list_w")
    mause = mess.find_all(class_="word_main_list_y")
    fanyi = mess.find_all(class_='word_main_list_s')
    for i in range(1,len(word)):
        key = word[i].span.get('title')
        f = mause[i].strong.string.split()
        y = fanyi[i].span.get('title')
        if len(f) == 0:#因为某些发音不存在,我们直接放弃,不存入
            continue
        word_mause[key]=[f[0],y,name]
    print('创建数据成功')
    return word_mause

def paqumusci(reponse):#爬取音频
    mause_list = []#音频URL列表
    word_list = []#单词列表
    mess = BeautifulSoup(reponse, 'lxml')
    mause = mess.find_all(class_="word_main_list_y")
    word = mess.find_all(class_='word_main_list_w')
    for i in range(1, len(mause)):
        word_list.append(word[i].span.get('title'))#加入列表
        mause_list.append(mause[i].a.get('id'))#加入列表
    for i in range(len(word_list)):#存入文件
        try:
            file = open('static//music//'+word_list[i] + '.mp3', 'wb')#打开文件,wb打开,以.mp3的格式打开
            flag = requests.get(mause_list[i])#爬取音频URL
            file.write(flag.content)#以二进制流写入
            file.close()#关闭文件
            print(word_list[i]+'存储成功')
        except:
            print(word_list[i] + '存储失败')

def cucun(word_mause):#爬取数据到数据库
    db = pymysql.connect(host='localhost', user='root', password='zcj123.abc', db='123', port=3306)#打开数据库
    print('打开数据库成功')
    cursor = db.cursor()#创建一个游标
    for key in word_mause:#word_mause是一个字典,模型:{'comment': ['[ˈkɔment]', 'n. 评论,意见;体现,写照', '四级必备词汇']}
        sql = 'INSERT INTO word(id, fayin, fanyi, music, word_tream) values(%s, %s, %s, %s, %s)'#构造sql语句
        try:
            cursor.execute(sql, (key,word_mause[key][0],word_mause[key][1],'music/'+key+'.mp3',word_mause[key][2]))
            db.commit()#插入数据
        except:
            db.rollback()#如果发生异常,则回滚(什么事情都没有发生)
    print('数据插入成功')
    db.close()#关闭数据库,记得一定要记得关闭数据库
    print('数据库成功关闭')

def creat_table():#创建一个表
    db = pymysql.connect(host='localhost', user='root', password='zcj123.abc', db='123', port=3306)
    print('打开数据库成功')
    cursor = db.cursor()
    sql = 'CREATE TABLE IF NOT EXISTS word (id VARCHAR(255) NOT NULL,fayin VARCHAR(255) NOT NULL,fanyi VARCHAR(255) NOT NULL,music VARCHAR(255) NOT NULL,word_tream VARCHAR(255) NOT NULL, PRIMARY KEY (id))'
    cursor.execute(sql)
    print('创建表成功')
    db.close()

def main():
    creat_table()#创建一个表
    url = 'http://word.iciba.com/'
    html = get_urlhtml(url)#得到首页的H5代码
    word_all = get_url(html)#得到所有classid可能取值的列表
    print('初始化成功开始爬取')
    for num in word_all:#word_all为classid所有可能的取值
        url_home = 'http://word.iciba.com/?action=courses&classid=' + str(num)#利用字符串拼接起来,得到URL网址
        html = get_urlhtml(url_home)
        mess = BeautifulSoup(html, 'lxml')
        li = mess.select('ul li')#解析得到所有的课时,其中li的长度就是课时的数量
        if len(li) <= 2:
            continue
        name = mess.select('.word_h2')#得到词书名称
        name = name[0]
        r = re.compile(".*?</div>(.*?)</div>")
        name = re.findall(r,str(name))
        name  = name[0]#得到词书名称
        print('开始爬取'+name)
        for j in range(1,len(li)+1):#利用课时的数量就是course的取值的特性,得到course的取值
            url = 'http://word.iciba.com/?action=words&class='+str(num)+'&course='+str(j)#得到单词所在的URL网站
            reponse = get_urlhtml(url)
            # print('开始爬取音频')
            # paqumusci(reponse)
            # print('音频文件爬取完成')
            print('开始爬取数据')
            word_mause = paqu_wangye(reponse,name)#得到数据字典
            print('开始存储数据')
            cucun(word_mause)#存储数据

if __name__ == '__main__':
    main()

猜你喜欢

转载自blog.csdn.net/onlylovecuracao/article/details/80768334