#!/usr/bin/env python # coding=utf-8 import requests from bs4 import BeautifulSoup import pymysql import re # 连接数据库 connect = pymysql.Connect( host='127.0.0.1', port=3306, user='root', passwd='123456', db='xunrui', charset='utf8' ) # 获取游标 cursor = connect.cursor() #行缩进只能用tab,否则报错不能用空格缩进 # 解析链接 def parse(url): # 给定一个初始的url url='http://www.jingyu.com/search/stack?pn=1' headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36' } html = requests.get(url, headers=headers) tests = html.text soup = BeautifulSoup(tests,'lxml') # <li class="book clearfix"> # <div class="clearfix"> # <a href="/novel/MdOkDBG2NXC3QD.html"><img class="pull-left cover" data-src="http://oss.ledu6.cn/book_img/28_335_1605065910.jpg" src="//p1.ssl.qhimg.com/d/inn/238e67af/defaultCover.png"/></a> # <div class="layout"> # <h3 class="name"><a href="/novel/MdOkDBG2NXC3QD.html">这该死的豪门,不嫁了</a></h3> # <p class="author"><a href="/search/?author=%E6%91%98%E6%98%9F%E6%8F%BD%E6%9C%88">摘星揽月</a> | <a href="/search/stack?category=66">婚恋家庭</a></p> # <p class="intr">简介:他说:“女人,帮帮我,我可以给你一切。” # 那夜纠缠后,她消失不见,那抹留在昂贵车座上的痕迹,犹如一朵玫瑰花。 满城搜寻,他再度出现在她面前,他说:“俞静雅,我可以给你一个家。”</p> # </div> # </div> # </li> # 找到li标签,该标签内有两个class属性,分别为book,clearfix data = soup.find_all('li',{'class':{'book','clearfix'}}) for i in data: name = i.h3.a.text #得到a后面的内容 zz_f1=i.p.text # 将得到的数据按|来拆分,拆分后为一个列表,其中有两个元素,但元素中有空格: 擎天柱 | 都市传奇 尽头 | 都市传奇 # 所以要使用strip来去除空格 zz_f1=zz_f1.split('|') #['擎天柱 ', ' 都市传奇'] ['尽头 ', ' 都市传奇'] zuoze = zz_f1[0].strip() #擎天柱 尽头 fenlei=zz_f1[1].strip() #都市传奇 都市传奇 print('书名:{0} 作者:{1} 类别:{2}'.format(name,zuoze,fenlei)) # 将得到的数据传送给MySQL mysql(name,zuoze,fenlei) # 解析完后再进行下一步解析 next_page(url) # 新建对象,然后将数据传入类中 def mysql(name,zuoze,fenlei): down = down_mysql(name,zuoze,fenlei) down.save_mysql() # 定义一个类,将连接MySQL的操作写入其中 class down_mysql: def __init__(self,name,zuoze,fenlei): self.name=name self.zuoze=zuoze self.fenlei=fenlei # self.connect = pymysql.Connect( # host='127.0.0.1', # port=3306, # user='root', # passwd='123456', # db='xunrui', # charset='utf8', # use_unicode = False # ) # self.cursor = self.connect.cursor() #上面链接数据库,下面保存数据到数据库中 def save_mysql(self): #print(self.name) try: sql = "INSERT INTO xiaoshuo(name,zuoze,fenlei) VALUES ('%s','%s','%s')" data = (self.name,self.zuoze,self.fenlei) # self.cursor.execute(sql % data) # self.connect.commit() cursor.execute(sql % data) connect.commit() print('成功插入', cursor.rowcount, '条数据') except Exception as e: #print('数据插入错误') print('程序出错',e) # 查找下一页url def next_page(nextpage): # 将得到的下一页的url由自己指定 # 匹配http://www.jingyu.com/search/stack?pn=1后面的数字 #group() 同group(0)就是匹配正则表达式整体结果, group(1) 列出第一个括号匹配部分,group(2) 列出第二个括号匹配部分,group(3) 列出第三个括号匹配部分。 # import re # a = "123abc456" # print re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(0) #123abc456,返回整体 # print re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(1) #123 # print re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(2) #abc # print re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(3) #456 a = re.search('pn=(.*)',nextpage).group(1) # 匹配http://www.jingyu.com/search/stack?pn=1数字前面的值 # 这里我不用字符串的split('='),主要为了练习正则 start_url=re.findall('.*pn=',nextpage)[0] #http://www.jingyu.com/search/stack?pn= #print(start_url) a=int(a) # 总共25页,只需要爬取25页就可以 if a<= 25: a+=1 nextpage = start_url+str(a) if a<=25: #只要url 还未到25页,那么继续解析 parse(nextpage) else: print('结束翻页') if __name__ == '__main__': # 给定一个初始的url url='http://www.jingyu.com/search/stack?pn=1' # 解析该url parse(url)