之前的文章我们介绍了一下 Python 中的正则表达式和与爬虫正则相关的 re 模块, 本章我们就利用正则表达式和 re 模块来做一个案例, 爬取《糗事百科》的糗事并存储到本地.
我们要爬取的网站链接是 https://www.qiushibaike.com/text/page/1/ .
我们要爬取的是里面的糗事, 在之前的文章中我们已经可以爬取整个 url 链接里的 html 内容, 那么我们就可以根据爬取到的 HTML 代码, 再通过 re 模块匹配我们想要的内容即可.
我们通过调用开发者工具检查 HTML 元素发现我们想要的内容在 <divclass="content"> ...... </div> 内, 根据这个我们可以写出代码如下:
- import urllib.request
- import re
- import ssl
- # 取消代理验证
- ssl._create_default_https_context = ssl._create_unverified_context
- url = "https://www.qiushibaike.com/text/page/1/"
- # User-Agent 头
- user_agent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) ApplewebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.157 Safari/537.36'
- headers = {'User-Agent': user_agent}
- req = urllib.request.Request(url, headers=headers)
- response = urllib.request.urlopen(req)
- # 获取每页的 HTML 源码字符串
- HTML = response.read().decode('utf-8')
- # 创建正则表达式规则对象, 匹配每页里的糗事内容, re.S 表示匹配全部字符串内容
- # re.S 如果没有 re.S 则是只匹配一行有没有符合规则的字符串, 如果没有则下一行重新匹配
- # 如果加上 re.S 则是将所有的字符串将一个整体进行匹配
- pattern = re.compile(r'<div.*?class="content">(.*?)</div>', re.S)
- # 将正则匹配对象应用到 HTML 源码字符串里, 返回这个页面里的所有糗事的列表
- content_list = pattern.findall(HTML)
- # 调用 dealPage() 处理糗事里的杂七杂八
- print(content_list)
最终我们打印结果如下:
从上面的打印结果可以看出我们已经拿到了我们想要的数据, 并且存储在了一个列表里, 那么接下来我们只需要再处理一下列表, 叫列表内杂七杂八的内容, 如上图中的 \n <span > 标签等去掉, 就是我们想要的内容了.
- for item in item_list:
- item = item.replace('<span>', "").replace('<span class="contentForAll"> 查看全文',"").replace("</span>","").replace("<br/>","").replace("\n", "")
- print(item)
- self.writePage(item)
上面的代码中 item_list 即为我们上面所获取到的 content_list 列表, 通过对列表的内容分析, 我们发现有 <span> ,<span class="contentForAll"> 查看全文,</span>,<br/>,\n 等多余内容, 我们通过 replace 方法将其转为空, 剩下的就是我们想要的内容了, 接下来就是存储到本地即可了.
上面就可以实现一个获取 糗事百科 的糗事的简单爬虫, 但是只能爬取单个页面的内容, 通过分析 url 我们发现 https://www.qiushibaike.com/text/page/1/ 中最后的 1 即为页码, 我们就可以根据这个页码逐一爬取更多页面的内容, 最终的代码如下:
- import urllib.request
- import re
- import ssl
- # 取消代理验证
- ssl._create_default_https_context = ssl._create_unverified_context
- class Spider:
- def __init__(self):
- # 初始化起始页位置
- self.page = 1
- # 爬取开关, 如果为 True 继续爬取
- self.switch = True
- def loadPage(self):
- """
- 作用: 打开页面
- """ url ="https://www.qiushibaike.com/text/page/"+ str(self.page) +"/"
- # User-Agent 头
- user_agent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.157 Safari/537.36'
- headers = {'User-Agent': user_agent}
- req = urllib.request.Request(url, headers=headers)
- response = urllib.request.urlopen(req)
- # 获取每页的 HTML 源码字符串
- HTML = response.read().decode('utf-8')
- # 创建正则表达式规则对象, 匹配每页里的糗事内容, re.S 表示匹配全部字符串内容
- # re.S 如果没有 re.S 则是只匹配一行有没有符合规则的字符串, 如果没有则下一行重新匹配
- # 如果加上 re.S 则是将所有的字符串将一个整体进行匹配
- pattern = re.compile(r'<div.*?class="content">(.*?)</div>', re.S)
- # 将正则匹配对象应用到 HTML 源码字符串里, 返回这个页面里的所有糗事的列表
- content_list = pattern.findall(HTML)
- # 调用 dealPage() 处理糗事里的杂七杂八
- self.dealPage(content_list)
- def dealPage(self, item_list):
- """
- @brief 处理得到的糗事列表
- @param item_list 得到的糗事列表
- @param page 处理第几页
- """
- for item in item_list:
- item = item.replace('<span>', "").replace('<span class="contentForAll"> 查看全文',"").replace("</span>","").replace("<br/>","").replace("\n", "")
- self.writePage(item)
- def writePage(self, text):
- """
- @brief 将数据追加写进文件中
- @param text 文件内容
- """ myFile = open("./duanzi.txt",'a') # 追加形式打开文件
- myFile.write(text + "\n\n")
- myFile.close()
- def startWork(self):
- """
- 控制爬虫运行
- """
- # 循环执行, 直到 self.switch == False
- while self.switch:
- # 用户确定爬取的次数
- self.loadPage()
- command = input("如果继续爬取, 请按回车 (退出输入 quit)")
- if command == "quit":
- # 如果停止爬取, 则输入 quit
- self.switch = False
- # 每次循环, page 页码自增 1
- self.page += 1
- print("爬取结束!")
- if __name__ == '__main__':
- # 定义一个 Spider 对象
- qiushiSpider = Spider()
- qiushiSpider.startWork()
最终会在本地添加一个 qiushi.txt 的文件, 结果如下:
来源: https://www.cnblogs.com/weijiutao/p/10876979.html