爬虫对于许多Python初学者来说都是一个好玩有趣的技能,但大多数人都是从网上得来的经验,会认为学习爬虫是件很难的事,像处理反爬机制以及反反爬,总是让人望而却步,今天我们来进行爬虫实操,需要注意爬虫本身并不违法,但恶意爬取文件将会涉及相关法律,为避免不必要的纠纷,本文采取一个不存在的网站进行演示,本文适合Python初学者以及爬虫初学者学习,博主是大一.所以讲的话和相关技能并不特别专业,望大家谅解
1. 导入模块部分
from urllib import request
from urllib.parse import quote
import string
import time
import json
from bs4 import BeautifulSoup
import codecs
import os
urllib.request
: 用于发送HTTP请求urllib.parse.quote
: 用于对URL进行编码string
: 提供字符串操作相关常量json
: 用于JSON数据的处理BeautifulSoup
: 用于解析HTML文档codecs
: 提供文件编码相关功能os
: 提供操作系统相关功能,如文件/目录操作2. 创建图片目录
if not os.path.exists("/images"): os.mkdir("/images")
检查是否存在
/images
目录,如果不存在则创建该目录,用于保存爬取的图片3. 设置请求头(重要!!!)
headers = {} headers["User-Agent"] = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36"
设置HTTP请求头中的User-Agent,模拟浏览器访问,避免被网站识别为爬虫。
4. 主函数
get_json(也重要!!!)
def get_json(character_arr): data={} for i in set(character_arr): print(i) url=r'https://baike.baidu.com/item/'+i url = quote(url, safe = string.printable) req = request.Request(url, headers=headers) response = request.urlopen(req, timeout=20)
接收一个字符数组
character_arr
作为参数(毕竟是要爬虫.一次只写一个参数太慢了.所以这里用一个数组)创建空字典
data
用于存储结果对字符数组去重后遍历每个字符
构建百度百科的URL,并进行URL编码
发送HTTP GET请求,设置超时时间为20秒
图片抓取部分(还没换呢,这个和上面的函数是连着的)
try: html = response.read().decode('utf-8') soup = BeautifulSoup(html, 'html.parser', ) res = soup.find(class_="summary-pic") pic_name = str(i) + '.jpg' img_src = res.find('img').get('src') request.urlretrieve(img_src,pic_name) except : print("找不到图片")
读取响应内容并解码为UTF-8
使用BeautifulSoup解析HTML
查找class为"summary-pic"的元素(百科的概要图片)
构建图片文件名(字符名+.jpg)
获取图片URL并下载保存
如果出错则打印"找不到图片"(这里百分百会出错,因为上面写的那个网站根本不存在,图片爬取部分到此结束)
Ⅰ.人物信息抓取部分(没换!!!)
res_key=soup.find_all(class_ ="basicInfo-item name") res_val=soup.find_all(class_ ="basicInfo-item value") key=[ik.get_text().strip().replace("\n","、") for ik in res_key] value = [iv.get_text().strip().replace("\n", "、") for iv in res_val] item=dict(zip(key,value)) data[str(i)]=item
查找所有class为"basicInfo-item name"的元素(基本信息键)
查找所有class为"basicInfo-item value"的元素(基本信息值)
使用列表推导式处理键和值,去除空白字符,替换换行符
将键和值组合成字典
将结果存入主数据字典,以字符名为键
Ⅱ.保存JSON数据(仍然没换!!!)
if not os.path.exists("../json"): os.mkdir("../json") f = codecs.open('../json/data.json','w','utf-8') f.write(json.dumps(data, ensure_ascii=False))
检查并创建json目录
以UTF-8编码打开文件
将数据字典转换为JSON格式写入文件,确保非ASCII字符正常显示(人物信息爬取部分到此结束)
5. 主程序入口
if __name__ == "__main__": character_arr=["马嘉祺","刘耀文","丁真","王源"] os.chdir(os.path.join(os.getcwd(), '/images')) get_json(character_arr)
获取字符数组
切换工作目录到图片保存目录
调用
get_json()
函数开始爬取数据
功能总结
这段代码主要完成以下功能:
从自定义模块获取一组字符
对每个字符,访问其页面
下载概要图片并保存
提取页面的基本信息表格(键值对形式)
将所有字符的信息保存为JSON文件
潜在问题(咱们需要爬的一些正常网站基本都不用管)
异常处理不足:当前代码对异常处理较为简单,可能遗漏某些错误情况
网络请求稳定性:没有实现重试机制,网络不稳定时可能失败
反爬虫风险:简单的User-Agent可能不足以应对反爬虫机制
性能考虑:串行请求效率较低,可考虑使用多线程/异步IO
代码结构:可以考虑将功能拆分为更小的函数,提高可维护性