👆点击“博文视点Broadview”,获取更多书讯
你是否有这样的问题,学 Python 语言之后,能做什么?Python的用途其实非常多,今天先来展示一个用Python采集漫画信息的实操案例01目标站点数据源分析▊ 爬去目标本次要爬取的网站是一个漫画网站,打开站点,呈现在我们面前的是 15660 部漫画信息,我们的目标是全部“拿下”。
为了降低学习难度,本文只介绍针对列表页进行抓取的过程,里面涉及的目标数据结构如下1. 漫画标题2. 漫画评分3. 漫画详情页链接4. 作者同时,在案例代码中需要同步保存漫画封面,并以封面文件名为漫画命名。
漫画详情页还存在大量的标签,因不涉及数据分析,故不再提取▊ 涉及的Python模块爬取模块requests,数据提取模块re,多线程模块 threading▊ 重点学习内容爬虫编写流程数据提取,重点掌握行内 CSS 提取。
CSV 格式文件存储变换IP 规避反爬,该目标网站有反爬机制▊ 列表页分析通过点击测试,得到的页码变化逻辑如下https://vol.moe/l/all,all,all,sortpoint,all,all,BL/1.htm。
https://vol.moe/l/all,all,all,sortpoint,all,all,BL/2.htmhttps://vol.moe/l/all,all,all,sortpoint,all,all,BL/524.htm
页面数据是服务器直接静态返回的,加载到 HTML 页面中。
目标数据所在的 HTML DOM 结构如下所示。
在正式编写代码前,可以先有针对性地处理一下正则表达式部分。▊ 匹配封面图在编写该部分正则表达式时,出现了下图所示的“折行+括号”问题。
正则表达式如下,这里重点需要注意 \s 可匹配换行符
下述正则表达式使用了分组命名的方法
(?P.*?)
(?P.*?)
对于动漫评分部分的匹配就非常简单了,直接编写如下正则表达式即可。(.*?)
02整理出的需求整理需求如下1. 开启 5 个线程对数据进行爬取2. 保存所有的网页源码3. 依次读取源码,提取元素到 CSV 文件中本案例将优先保存网页源码到本地,然后对本地 HTML 文件进行处理。03编码时间在编码测试的过程中,我们发现该网站存在反爬措施,会直接封杀爬虫程序的IP,导致程序还没有跑起来,就结束了再次测试,发现反爬技术使用重定向操作,即服务器发现是爬虫后,直接返回状态码 302,并重定向谷歌网站。
IP受限制的时间大概是 24 个小时,因此如果希望爬取到全部数据,需要通过不断切换 IP 和 UA ,将 HTML 静态文件保存到本地下述代码可以判断目标网站返回的状态码,如果为 302,则更换代理 IP,再次爬取。
import requestsimport reimport threadingimport timeimport random# 以下为UA列表,为节省篇幅只保留两项,完整版请联系作者获取USER_AGENTS = [
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; AcooBrowser; .NET CLR 1.1.4322; .NET CLR 2.0.50727)"
,"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Acoo Browser; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.0.04506)"
,]# 循环获取 URLdefget_image(base_url, index): headers = {"User-Agent": random.choice(USER_AGENTS) }
print(f"正在抓取{index}")try: res = requests.get(url=base_url, headers=headers, allow_redirects=
False, timeout=10) print(res.status_code)# 当服务器返回 302状态码之后while res.status_code == 302:# 可直接访问 http://118.24.52.95:5010/get/ 获得一个代理IP
ip_json = requests.get("http://118.24.52.95:5010/get/", headers=headers).json() ip = ip_json[
"proxy"] proxies = {"http": ip,"https": ip } print(proxies)# 使用代理IP继续爬取
res = requests.get(url=base_url, headers=headers, proxies=proxies, allow_redirects=False, timeout=
10) time.sleep(5) print(res.status_code)else: html = res.text# 读取成功,保存为 html 文件
with open(f"html/{index}.html", "w+", encoding="utf-8") as f: f.write(html) semaphore.release()
except Exception as e: print(e) print("睡眠 10s,再去抓取") time.sleep(10) get_image(base_url, index)
if __name__ == __main__: num = 0# 最多开启5个线程 semaphore = threading.BoundedSemaphore(5) lst_record_threads = []
for index in range(1, 525): semaphore.acquire() t = threading.Thread(target=get_image, args=(
f"https://vol.moe/l/all,all,all,sortpoint,all,all,BL/{index}.htm", index)) t.start() lst_record_threads.append(t)
for rt in lst_record_threads: rt.join()只开启了 5 个线程,爬取过程如下所示。
经过 20 多分钟的等待,524 页数据全部以静态页形式保存在了本地 HTML 文件夹中。
当文件全部存储到本地之后,再进行数据提取就非常简单了编写如下提取代码,使用 os 模块import osimport reimport requestsdefreade_html(): path = 。
r"E:\pythonProject\test\html"# 读取文件 files = os.listdir(path)for file in files:# 拼接完整路径 file_path = os.path.join(path, file)
with open(file_path, "r", encoding="utf-8") as f: html = f.read()# 正则提取图片 img_pattern = re.compile(
)# 正则提取得到 score_pattern = re.compile(
(.*?)
) img_urls = img_pattern.findall(html)details = title_pattern.findall(html) scores = score_pattern.findall(html)# save(details, scores)
for index, url in enumerate(img_urls): save_img(details[index][1], url)# 数据保存成 csv 文件def
save(details, scores):for index, detail in enumerate(details): my_str = "%s,%s,%s,%s\n" % (detail[
1].replace(",", ","), detail[0], detail[2].replace(",", ","), scores[index])with open("./comic.csv",
"a+", encoding="utf-8") as f: f.write(my_str)# 图片按照动漫标题命名defsave_img(title, url): print(
f"正在抓取{title}--{url}") headers = {"User-Agent": "Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; fr) Presto/2.9.168 Version/11.52"
}try: res = requests.get(url, headers=headers, allow_redirects=False, timeout=10) data = res.content
with open(f"imgs/{title}.jpg", "wb+") as f: f.write(data)except Exception as e: print(e)
if __name__ == __main__:reade_html()代码提取到 csv 文件如下所示。
关于详情页,即动漫的更新信息,可以使用上述逻辑再次爬取04总结完全学会本文中的操作,不仅需要用到 Python 的基础知识,还要掌握Python requests 模块、正则模块 re 、文件读写、多线程模块的相关内容。
想要快速学习这些内容,可以从阅读《滚雪球学Python》这本书开始滚雪球学 Python,书如其名,教授大家用类似滚雪球的思维学习 Python,第一遍浏览 Python 核心内容,第二遍补齐周边知识,第三遍夯实,第四遍拔高。
。每一遍滚雪球式的学习,都能丰富自己的知识。
限时五折优惠,快快扫码抢购吧!发布:刘恩惠审核:陈歆懿如果喜欢本文欢迎在看丨留言丨分享至朋友圈 三连
Python,30年上位之路!
点击阅读原文,查看本书详情!
亲爱的读者们,感谢您花时间阅读本文。如果您对本文有任何疑问或建议,请随时联系我。我非常乐意与您交流。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。