BeautifulSoup爬虫之保存到mysql数据库
来源:互联网 发布:淘宝上正规药店是哪个 编辑:程序博客网 时间:2024/06/03 22:33
爬取起点中文网 数据保存到mysql数据库
一.分析网页
目标网站:起点中文网
目标数据:类别(categoryName)小说书名(bookName) 小说链接(middleUrl)字数(wordsNums) 作者(updateTiems) 最新章节更新时间(authorName)
目标urls:”https://www.qidian.com/all?chanId=1&orderId=&style=2&pageSize=20&siteid=1&pubflag=0&hiddenField=0&page=1” 我们选取奇幻类的作测试 把page移动到最后方便后面的url拼接。
二.获取urls列表
1.取总页数
我们爬取多页的数据这时候就需要多个url了,根据上面的分析我们知道每一页page都不同所以我们只要改变url最后的”page=”就可以了 ,如果我们想获取这个系列所有的页数我们可以定位总页数。如图:
代码如下:
#总取页数 def getPages(self,url): htmlContent = self.getResponseContent(url) soup = BeautifulSoup(htmlContent, 'lxml') tags=soup.find('ul',attrs={'class':'lbf-pagination-item-list'}) #totalPages=tags.find_all('a')[-2].get('data-page') 取总页数 totalPages=1 #测试用 self.log.info(u'总页数为%s' %totalPages) return totalPages
2.根据总页数拼接url
# 根据pageSum拼装要爬取的地址 def getUrls(self,urlBase,pages): ulrs=[] ul=self.urlBase.split('=') for i in range(int(pages)+1): ul[-1]=str(i) url='='.join(ul) ulrs.append(url) self.log.debug('----待爬取的地址有:' + url) return ulrs
三.爬取目标数据
有了url我们就可以开始爬取我们想要的数据了!记得分析网页来进行元素定位。
#数据爬取 利用lxml解析 def spider(self,urls): for ulr in urls: htmlContent = self.getResponseContent(url) soup = BeautifulSoup(htmlContent, 'lxml') tableTag=soup.find_all('table',attrs={'class':'rank-table-list all'})[0] trTags=tableTag.tbody.find_all('tr') for tag in trTags: item=BookItem() tags=tag.find_all('td') item.categoryName=tags[0].getText().strip() item.bookName=tags[1].getText().strip() item.middleUrl=tags[1].find('a').get('href').strip() item.wordsNums=tags[3].getText().strip() item.authorName=tags[4].getText().strip() item.updateTiems=tags[5].getText().strip() self.items.append(item) self.log.info(u'爬取%s 成功' %(item.categoryName))
四.保存数据到mysql
保存到text文本的方法这里就不再啰嗦。今天的重点是如何保存到mysql数据库。python提供了pymysql模块进行数据库相关操作
python 2—-> import MYSQLdb
python 3—-> import pymysql
没有安装记得安装pymysql
记得提前在数据库中建表!!!!!
建表:
代码如下:
#! -*- encoding:utf-8 -*-"""保存到mysql数据库"""import pymysqlpymysql.install_as_MySQLdb()class SaveBooksDate(object): def __init__(self,items): self.host='localhost' self.port=3306 self.user='root' self.password='a' self.db='test' self.run(items) def run(self,items): #创建连接 conn=pymysql.connect(host=self.host,port=self.port,user=self.user,password=self.password,db=self.db,charset='utf8') # 使用 cursor() 方法创建一个游标对象 cursor cur = conn.cursor() params=[] for item in items: params.append((item.categoryName, item.middleUrl, item.bookName, item.wordsNums, item.updateTiems,item.authorName)) sql="insert into qidianbooks(categoryName,middleUrl,bookName,wordsNums,updateTiems,authorName) values(%s, %s, %s, %s, %s, %s )" try: # 执行SQL ret=cur.executemany(sql,params) conn.commit() #提交 print(u'添加成功,共添加%s 条数据' %str(ret)) except Exception as e: print(e) conn.rollback() cur.close() # 关闭游标 conn.close() # 关闭连接
这里是新建的文件 记得在爬虫文件引入函数以及调用SaveBooksDate()函数
引入:
from save2mysql import SaveBooksDate
调用:
def __init__(self,url): self.urlBase=url self.log=MyLog() self.pages=self.getPages(self.urlBase) #根据urlBase取页数 self.items=[] self.urls=[] self.urls = self.getUrls(self.urlBase,self.pages) #根据页数获取url # 开始爬取 self.spider(self.urls) # 存 #self.pipelines(self.items) #存入mysql SaveBooksDate(self.items)
连接数据库的时候出了个bug:
后来才发现太粗心了少了一个括号:
以后一定要细心细心再细心!
四.结果及源代码
结果:
注:直接在mysql中读取可能乱码 这里我用navicat查看!
1.日志类
代码:
#! -*- encoding:utf-8 -*-\"""乱码问题 解决方式一:#! -*- encoding:utf-8 -*-\ 方式二:u'哈哈哈' 字符串以unicode格式存储"""import loggingimport getpassimport sysclass MyLog(object): #构造方法 def __init__(self): self.user=getpass.getuser() self.logger=logging.getLogger(self.user) self.logger.setLevel( logging.DEBUG ) #日志的级别 critical error warn info debug #定义日志文件 self.logFile=sys.argv[0][0:-3]+'.log' # 从命令行参数中取出第一个参数,并取从0开始到 倒数第三个字符 拼接成文件名 self.formatter=logging.Formatter('%(asctime) -12s %(levelname) -8s %(name) -10s %(message)-12s\r\n') #日志输出的格式 #日志输出到文件 logging有三个内置的Handler, self.logHand=logging.FileHandler(self.logFile, encoding='utf8') self.logHand.setFormatter( self.formatter ) #设置 格式 self.logHand.setLevel( logging.DEBUG ) #设置 级别 #日志输出 到屏幕,这是标准输出流 self.logHandSt=logging.StreamHandler() self.logHandSt.setFormatter( self.formatter ) self.logHand.setLevel( logging.DEBUG ) #将两个Handler加入到 logger中 self.logger.addHandler( self.logHand ) self.logger.addHandler( self.logHandSt ) #重新定义logger中的日志输出的级别的方法 def debug(self,msg): self.logger.debug(msg) def info(self,msg): self.logger.info(msg) def warn(self,msg): self.logger.warn(msg) def error(self,msg): self.logger.error(msg) def critical(self,msg): self.logger.critical(msg)if __name__=='__main__': mylog=MyLog() mylog.debug(u'debug测试') mylog.info(u'info测试') mylog.warn(u'warn测试') mylog.error(u'error测试') mylog.critical(u'critical测试')
2.爬虫类
代码:
#! -*- encoding:utf-8 -*-#目标地址:https://www.qidian.com/all?chanId=1&orderId=&style=2&pageSize=20&siteid=1&pubflag=0&hiddenField=0&page=1from MyLog import MyLogimport stringfrom urllib.parse import quotefrom urllib import errorimport urllib.requestfrom bs4 import BeautifulSoupfrom save2mysql import SaveBooksDateimport codecsimport timeimport os#pymysqlclass BookItem(object): categoryName=None middleUrl=None bookName=None wordsNums= None updateTiems= None authorName= Noneclass GetBook(object): def __init__(self,url): self.urlBase=url self.log=MyLog() self.pages=self.getPages(self.urlBase) #根据urlBase取页数 self.items=[] self.urls=[] self.urls = self.getUrls(self.urlBase,self.pages) #根据页数获取url # 开始爬取 self.spider(self.urls) # 存 #self.pipelines(self.items) SaveBooksDate(self.items) # 根据pageSum拼装要爬取的地址 def getUrls(self,urlBase,pages): ulrs=[] ul=self.urlBase.split('=') for i in range(int(pages)+1): ul[-1]=str(i) url='='.join(ul) ulrs.append(url) self.log.debug('----待爬取的地址有:' + url) return ulrs #取页数 def getPages(self,url): htmlContent = self.getResponseContent(url) soup = BeautifulSoup(htmlContent, 'lxml') tags=soup.find('ul',attrs={'class':'lbf-pagination-item-list'}) #totalPages=tags.find_all('a')[-2].get('data-page') totalPages=1 self.log.info(u'总页数为%s' %totalPages) return totalPages #数据爬取 利用lxml解析 def spider(self,urls): for ulr in urls: htmlContent = self.getResponseContent(url) soup = BeautifulSoup(htmlContent, 'lxml') tableTag=soup.find_all('table',attrs={'class':'rank-table-list all'})[0] trTags=tableTag.tbody.find_all('tr') for tag in trTags: item=BookItem() tags=tag.find_all('td') item.categoryName=tags[0].getText().strip() item.bookName=tags[1].getText().strip() item.middleUrl=tags[1].find('a').get('href').strip() item.wordsNums=tags[3].getText().strip() item.authorName=tags[4].getText().strip() item.updateTiems=tags[5].getText().strip() self.items.append(item) self.log.info(u'爬取%s 成功' %(item.categoryName)) #读取URL指定的网页内容 def getResponseContent(self,url): #对地址的中文进行编码 try: url=quote(url,safe=string.printable) response=urllib.request.urlopen(url) except error.URLError as e: self.log.error(u'python爬取%s 出错了' %url) print (e) else: self.log.info(u'python爬取%s 成功' %url) return response.read() #爬取的信息保存 def pipelines(self, items): filePrefixName =time.strftime('%Y%m%H%M%s',time.localtime()) fileName=os.path.expanduser("~")+os.path.sep+filePrefixName+u'.txt' with codecs.open(fileName, 'w', 'utf8') as fp: for item in items: fp.write('%s %s %s %s %s %s \n' % (item.categoryNam, item.bookName, item.middleUrl, item.wordsNums, item.authorName, item.updateTiems)) self.log.info(u'标题为 %s 的小说信息保存成功' % (item.categoryNam))if __name__=='__main__': url=u'https://www.qidian.com/all?chanId=1&orderId=&style=2&pageSize=20&siteid=1&pubflag=0&hiddenField=0&page=1' tb=GetBook(url)"""保存到mysql库python 2 import MYSQLdbpython 3 import pymysql"""
3.存数据库类
数据库代码如上—->四.保存数据到mysql
以后会写使用scrapy如何保存数据到mysql。大家也发现了仅仅一个分类就有几千页的数据使用爬虫爬取多页数据IP可能会被封掉以后我会结合实例演示如何反反爬虫。
- BeautifulSoup爬虫之保存到mysql数据库
- BeautifulSoup爬虫之保存CSV文件
- 爬虫之BeautifulSoup
- python爬虫之BeautifulSoup
- python爬虫之-BeautifulSoup
- 网络爬虫之beautifulsoup
- python爬虫之BeautifulSoup
- 使用python爬虫抓取页面之后,将页面保存到Mysql数据库中
- Nodejs实现简单爬虫,将爬到的数据以json数据格式保存到MySQL数据库中
- Scrapy网络爬虫实战[保存为Json文件及存储到mysql数据库]
- scrapy框架爬虫将数据保存到MySQL数据库(20170214)
- 保存数据到MySql数据库——我用scrapy写爬虫(二)
- python爬虫之BeautifulSoup入门
- python爬虫之BeautifulSoup库
- Python-网络爬虫之BeautifulSoup
- Pyspider实例之抓取数据并保存到MySQL数据库
- Python爬虫系列之----Scrapy(八)爬取豆瓣读书某个tag下的所有书籍并保存到Mysql数据库中去
- 【Python爬虫】requests+Beautifulsoup存入数据库
- 判断无向图图的连通性,邻接矩阵表示
- JavaFX之实现桌面应用的界面跳转
- UBOOT timer设置(基于S3C2440)
- australian dairy
- Python爬虫BeautifulSoup用法(1)
- BeautifulSoup爬虫之保存到mysql数据库
- 二分查找---河中跳房子
- 谁记得
- Qt 5设置自定义注释片段或者代码片段
- JSP向Servlet传递数组参数
- Jackson之jackson-databind
- 使用交叉存取得到更快推荐算法
- git github 写的比较好的博文
- 数据结构与算法(Python)——常见数据结构Part2(Common data structures)