爬取目标
爬取 60+ 奥特曼,目标数据源: http://www.ultramanclub.com/?page_id=1156
使用框架
requests,re
重点学习的内容
get 请求;
requests 请求超时设定,timeout 参数;
re 模块正则表达式;
数据去重;
URL 地址拼接。
列表页分析
经过开发者工具的简单查阅,得到全部奥特曼卡片所在的 DOM 标签为
详情页所在的标签为 <a = href=“详情页” ……
稍后根据实际请求数据,整理一下正则表达式。整理需求如下
1.通过列表页,爬取全部奥特曼详情页的地址;
2。进入详情页,爬取详情页里面的图片地址;
3。下载保存图片;
代码实现
爬取全部奥特曼详情页地址在爬取列表页的过程中,发现奥特曼页面使用了 iframe 嵌套,该手段也属于最简单的反爬手段,提取真实链接即可,故目标数据源切换为 http://www.ultramanclub.com/allultraman/ 。
import requests import re import time # 爬虫入口 def run(): url = "http://www.ultramanclub.com/allultraman/" try: # 网页访问速度慢,需要设置 timeout res = requests.get(url=url, timeout=10) res.encoding = "gb2312" html = res.text get_detail_list(html) except Exception as e: print("请求异常", e)
# 获取全部奥特曼详情页 def get_detail_list(html): start_index = '<ul class="lists">' start = html.find(start_index) html = html[start:] links = re.findall('<li class="item"><a href="(.*)">', html) print(len(links)) links = list(set(links)) print(len(links)) if __name__ == '__main__': run()
在代码编写过程中,发现网页访问速度慢,故设置 timeout 属性为 10,防止出现异常,
正则表达式匹配数据时,出现了重复数据,通过 set 集合进行去重,最终在转换为 list。
接下来对获取到的 list 进行二次拼接,获取详情页地址。
进行二次拼接得到的详情页地址,代码如下:
# 获取全部奥特曼详情页 def get_detail_list(html): start_index = '<ul class="lists">' start = html.find(start_index) html = html[start:] links = re.findall('<li class="item"><a href="(.*)">', html) print(len(links)) links = list(set(links)) print(len(links))
爬取全部奥特曼大图
该步骤先获取网页标题的方式,然后用该标题,对奥特曼大图爬取命名。
爬取逻辑非常简单,只需要循环上文爬取到详情页地址,然后通过正则表达式进行匹配即可。
修改代码如下所示,关键节点查看注释。
import requests import re import time # 声明 UA headers = { "User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.85 Safari/537.36" } # 存储异常路径,防止出现爬取失败情况 error_list = [] # 爬虫入口 def run(): url = "http://www.ultramanclub.com/allultraman/" try: # 网页访问速度慢,需要设置 timeout res = requests.get(url=url, headers=headers, timeout=10) res.encoding = "gb2312" html = res.text return get_detail_list(html) except Exception as e: print("请求异常", e) # 获取全部奥特曼详情页 def get_detail_list(html): start_index = '<ul class="lists">' start = html.find(start_index) html = html[start:] links = re.findall('<li class="item"><a href="(.*)">', html) # links = list(set(links)) links = [ f"http://www.ultramanclub.com/allultraman/{i.split('/')[1]}/" for i in set(links)] return links def get_image(url): try: # 网页访问速度慢,需要设置 timeout res = requests.get(url=url, headers=headers, timeout=15) res.encoding = "gb2312" html = res.text print(url) # 获取详情页标题,作为图片文件名 title = re.search('<title>(.*?)\[', html).group(1) # 获取图片短连接地址 image_short = re.search( '<figure class="image tile">[.\s]*?<img src="(.*?)"', html).group(1) # 拼接完整图片地址 img_url = "http://www.ultramanclub.com/allultraman/" + image_short[3:] # 获取图片数据 img_data = requests.get(img_url).content print(f"正在爬取{title}") if title is not None and image_short is not None: with open(f"images/{title}.png", "wb") as f: f.write(img_data) except Exception as e: print("*"*100) print(url) print("请求异常", e) error_list.append(url) if __name__ == '__main__': details = run() for detail in details: get_image(detail) while len(error_list) > 0: print("再次爬取") detail = error_list.pop() get_image(detail) print("奥特曼图片数据爬取完毕")
运行代码,看到图片接连存储到本地 images 目录中。
转载于:https://blog.csdn.net/hihell/article/details/117458985