Python3 selector 爬取豆瓣读书信息并将其存入Excel表格或mysql数据库

    xiaoxiao2022-07-05  194

    一. 爬取豆瓣读书信息

    这里只爬取了豆瓣读书信息的书名和评分;最后面补充了爬取书封面,以及将其保存的代码。 爬取方式是根据网页中所需信息对应的selector来查找。 例如: https://book.douban.com/tag/小说 页面中,爬取这本书的名字, 则先将光标悬在书名“活着”之上,然后,右键选择“检查”,就看到如下所示的部分: 然后,光标悬在这部分上面,右键选择“copy”—》“copy selector”,就复制得到该书名的selector: #subject_list > ul > li:nth-child(1) > div.info > h2 > a 其中,nth-child(1)表示这是本页第一本书,去掉 :nth-child(1) ,可以一次爬取到这一页所有的书名。注:我是以Google为例

    #coding=utf-8 import urllib.request import lxml.etree from cssselect import GenericTranslator, SelectorError def loadDoubanScore(url, tag, start): ''' 爬取豆瓣读书的评分: url: 网址 tag: 读书标签,eg: '小说' start: 开始数,由于每一页面只有有限的书籍信息,需要翻页,第一页的start=0,第二页的start=20(这个根据第一页有多少书籍决定),以此类推 ''' tag = urllib.request.quote(tag) #将中文转化为url的形式 url = url + tag + '?start=' + str(start)+'&type=T' request = urllib.request.Request(url=url) request.add_header(key="user-agent", val="Mozilla/5.0") #模拟Mozilla浏览器进行爬虫 response = urllib.request.urlopen(url=request) html = response.read().decode('utf-8') dataList = [] try: expressionName = GenericTranslator().css_to_xpath('#subject_list > ul > li > div.info > h2 > a') #括号中为书名的selector expressionScore = GenericTranslator().css_to_xpath('#subject_list > ul > li > div.info > div.star.clearfix > span.rating_nums') #在这里填入从网页源码中复制的selector except SelectorError: print('Invalid selector.') document = lxml.etree.HTML(text=html) for name, score in zip(document.xpath(expressionName), document.xpath(expressionScore)): dataList.append((name.get('title'), score.text)) # print(score.text) #获取标签之间的内容用text,<>获取这部分内容</> # print(name.get('title')) #根据属性获取信息用get(属性), <a title="活着"></a> 获取标签内部某属性的对应的值 return dataList url = "https://book.douban.com/tag/" for page in range(3): dataList = loadDoubanScore(url, tag="小说", start=page*20) #一页中含20条记录 for dl in dataList: print(dl[0], " ", dl[1])

    爬取的部分结果为:

    二. 将上面爬取的数据存入Excel表格中

    我的代码都是写在同一python文件中,所以下面的代码中没写之前用到的库,以及这条语句url = “https://book.douban.com/tag/”

    '''将爬取数据放入Excel表格中''' import xlwt savePath = r"E:\douban.xls" wb = xlwt.Workbook(encoding='ascii', style_compression=0) sheet = wb.add_sheet(sheetname='sheet1', cell_overwrite_ok=True) #——————————下面这部分是格式设置,可选———————————————— font = xlwt.Font() font.name = "Arial" #字体名 font.bold = True #加粗 alignment = xlwt.Alignment() alignment.horz = xlwt.Alignment.HORZ_CENTER #居中 style = xlwt.XFStyle() style.font = font style.alignment = alignment #———————————————————————————————————————————————— sheet.col(1).width = 6000 #初始为2962, 加宽第一列 for i, bt in enumerate(['ID', 'bookName', 'score']): sheet.write(r=0, c=i, label=bt, style=style) #若是设置了style,就加上style参数,若没设置,就去掉style—— sheet.write(r=0, c=i, label=bt) id = 1 for page in range(2): dataList = loadDoubanScore(url, tag="小说", start=page*20) #调用上面的爬取数据的方法 for i in range(len(dataList)): sheet.write(r=id, c=0, label=id, style=style) sheet.write(r=id, c=1, label=dataList[i][0], style=style) sheet.write(r=id, c=2, label=float(dataList[i][1]), style=style) id += 1 wb.save(savePath)

    结果如下:

    三. 将上面爬取数据存入mysql数据库中

    我的代码都是写在同一python文件中,所以下面的代码中没写之前用到的库,以及这条语句url = “https://book.douban.com/tag/” 当然,前提是你安装有mysql

    '''将爬取的数据存入数据库中''' import pymysql host = "localhost" user = "root" #mysql中你的用户名 pwd = "xxx" #你的root对应的密码 dbName = "doubanRecord" #将存储数据的数据库名 try: connection = pymysql.connect(host=host, user=user, password=pwd, db=dbName, charset='utf8mb4', cursorclass=pymysql.cursors.DictCursor) except pymysql.err.InternalError as err: if(err.args[0] == 1049): print(err.args[1], " ", "need create db") connection = pymysql.connect(host=host, user=user, password=pwd, charset='utf8mb4', cursorclass=pymysql.cursors.DictCursor) with connection.cursor() as cursor: cursor.execute("CREATE DATABASE " + dbName) #创建数据库 connection.commit() #如果是修改数据库内容的,需要加上这一句 finally: with connection.cursor() as cursor: try: # 使用预处理语句创建表,[表名:DOUBAN, 第一列名:ID, 第二列名: 书名(Book_Name), 第三列名:评分(Score)] sql = """CREATE TABLE DOUBAN ( ID INT NOT NULL AUTO_INCREMENT, Book_Name VARCHAR(100) NOT NULL, Score FLOAT(2,1), PRIMARY KEY (ID)) ENGINE=InnoDB DEFAULT CHARSET=utf8;""" cursor.execute(sql) #创建数据表 except pymysql.err.InternalError as err: print(err) finally: for page in range(0, 3): #准备爬取前3页,每一页有20条记录 dataList = loadDoubanScore(url, tag="小说", start=page*20) #调用前面的爬取数据的方法 for item in dataList: #sql = "INSERT INTO `DOUBAN` (`Book_Name`, `Score`) VALUES ("活着", 9.3)" sql = "INSERT INTO `DOUBAN` (`Book_Name`, `Score`) VALUES "+ str(item) cursor.execute(sql) connection.commit() connection.close()

    结果如下:

    四. 爬取书封面,并将其保存在本地

    #coding=utf-8 import urllib.request import lxml.etree from cssselect import GenericTranslator, SelectorError import os def loadDoubanScore(url, tag, start): ''' 爬取豆瓣读书的评分: url: 网址 tag: 读书标签,eg: '小说' start: 开始数,由于每一页面只有有限的书籍信息,需要翻页,第一页的start=0,第二页的start=20(这个根据第一页有多少书籍决定),以此类推 ''' tag = urllib.request.quote(tag) url = url + tag + '?start=' + str(start)+'&type=T' request = urllib.request.Request(url=url) request.add_header(key="user-agent", val="Mozilla/5.0") #模拟Mozilla浏览器进行爬虫 response = urllib.request.urlopen(url=request) html = response.read().decode('utf-8') dataList = [] imgUrlList = [] try: expressionName = GenericTranslator().css_to_xpath('#subject_list > ul > li > div.info > h2 > a') #括号中为书名的selector expressionScore = GenericTranslator().css_to_xpath('#subject_list > ul > li > div.info > div.star.clearfix > span.rating_nums') #在这里填入从网页源码中复制的selector expressionImg = GenericTranslator().css_to_xpath('#subject_list > ul > li > div.pic > a > img') #括号中为书封面的selector except SelectorError: print('Invalid selector.') document = lxml.etree.HTML(text=html) for name, score, img in zip(document.xpath(expressionName), document.xpath(expressionScore), document.xpath(expressionImg)): dataList.append((name.get('title'), score.text)) imgUrlList.append(img.get('src')) # print(score.text) #获取标签之间的内容 # print(name.get('title')) #根据属性获取信息 return dataList, imgUrlList url = "https://book.douban.com/tag/" saveImgPath = r'F:\pachong\doubanTushu' id = 0 for page in range(1): dataList, imgUrlList = loadDoubanScore(url, tag="小说", start=page*20) #一页中含20条记录 for im in imgUrlList: urllib.request.urlretrieve(im, os.path.join(saveImgPath, str(id)+'_'+dataList[id][0]+'.jpg')) id += 1

    结果如下:

    参考:

    【1】pymysql库的用法:https://pymysql.readthedocs.io/en/latest/user/examples.html 【2】Python3 MySQL 数据库连接 - PyMySQL 驱动:https://www.runoob.com/python3/python3-mysql.html 【3】xlwt 用法:https://xlwt.readthedocs.io/en/latest/api.html 【4】Python xlwt.XFStyle() Examples:https://www.programcreek.com/python/example/20560/xlwt.XFStyle 【5】python爬虫介绍:https://www.runoob.com/w3cnote/python-spider-intro.html

    最新回复(0)