前些日子发现了一个xkcd的中文站,想把它们都爬下来。

URL:https://xkcd.in/

这里先给大家欣赏一幅:

(图片来自:你最喜欢 xkcd 的哪一张? - 知乎 (zhihu.com))

废话不多说,我们现在就开始吧。

一、单线程下载

1、下载单页图片

我们先下最新的一张:

右键点击图片,打开检查:

发现图片存在class为comic-body的div中。

事实上,我们可以打开页面源代码,发现……

图片存在第一个img标签中。我们可以编写代码:

import requests, os, bs4, urllib
url = 'https://xkcd.in/'
os.makedirs('xkcd',exist_ok = True)
res = requests.get(url)
res.encoding = 'utf-8'
soup = bs4.BeautifulSoup(res.text,'html.parser')
img_tag = soup.img
print(img_tag)
url = 'https://xkcd.in' + img_tag.get('src')
print('url:',url)
urllib.request.urlretrieve(url,'./xkcd/' + img_tag.get('alt') + '.jpg')

下载完成!

2、获取下一个页面

打开开发者模式,发现下一篇的链接存在 class 为 nextLink 的 a 标签里。

这很简单,只需要这样获取:

url = 'https://xkcd.in/' + soup.find('div',class_ = "nextLink").find('a').get('href')

3、整合

把代码整合起来,就可以下载全站漫画了:

import requests, os, bs4, urllib, time
url = 'https://xkcd.in'
os.makedirs('xkcd',exist_ok = True)
while True:res = requests.get(url)res.encoding = 'utf-8'soup = bs4.BeautifulSoup(res.text,'html.parser')img_tag = soup.imgimg_url = 'https://xkcd.in' + img_tag.get('src')print('正在下载:',img_url)urllib.request.urlretrieve(img_url,'./xkcd/' + img_tag.get('alt') + '.jpg')if 'id=1' == url[-4:]:    #最小id是1breakurl = 'https://xkcd.in/' + soup.find('div',class_ = "nextLink").find('a').get('href')
input('下载完成')

二、多线程下载

对于多线程,我知道一个很简单的库 —— multitasking 库。

只需要用 pip 安装即可:

pip install multitasking

使用方式:

import time
def main():time.sleep(1)
start = time.time()
for i in range(5):main()
end = time.time()
print(end - start)#输出:5.00570011138916

这段代码要5秒执行。

现在我们用多线程执行:

import time, multitasking@multitasking.task
def main():time.sleep(1)
start = time.time()
for i in range(5):main()
multitasking.wait_for_tasks()    # 等待全部线程执行完毕
end = time.time()
print(end - start)# 输出:1.002472162246704

由于用多线程执行,所以时间少很多。

改编

我们可以建立多个线程,每个线程下载 50 个页面。

我们先编写一个分块函数:

#参考自:https://zhuanlan.zhihu.com/p/369531344def split_(start, end, step):# 分多块parts = [(start, min(start+step, end))for start in range(0, end, step)]return parts

再改编一下下载程序:

def d(start_id,end_id):for id in range(start_id,end_id):print(id,end = '')url = 'https://xkcd.in/comic?lg=cn&id='+str(id)res = requests.get(url)res.encoding = 'utf-8'res.raise_for_status()   # 返回请求的状态soup = bs4.BeautifulSoup(res.text,'html.parser')comicele = soup.find('div',class_ = "comic-body")if comicele == None:print(',无图片')continuecomicele = comicele.find_all('img')[0]#print(comicele)if comicele == []:print('图片未找到')else:comicurl = 'https://xkcd.in/' + comicele.get('src')#res = requests.get(comicurl)name = soup.find_all('h1')[1].text.replace(' ',"").replace('\r\n',"").replace('\\',"").replace(r"/","").replace(r"/","").replace(':',"").replace(":","").replace("*","").replace('''"''',"").replace('<',"").replace('>',"").replace('|',"")print('正在下载:',"D:\\python\\漫画爬虫\\xkcd_2\\%s.png"%(name))urllib.request.urlretrieve(comicurl,"D:\\python\\漫画爬虫\\xkcd_2\\%s.png"%(name))    # urllib.request.urlretrieve函数下载文件。

整合全部代码:

import requests,os,bs4,urllib,multitasking
from time import sleep
import signal
signal.signal(signal.SIGINT, multitasking.killall)          # ctrl + c 一次终止已开启的全部线程@multitasking.task
def d(start_id,end_id):for id in range(start_id,end_id):print(id,end = '')url = 'https://xkcd.in/comic?lg=cn&id='+str(id)res = requests.get(url)res.encoding = 'utf-8'res.raise_for_status()   # 返回请求的状态soup = bs4.BeautifulSoup(res.text,'html.parser')comicele = soup.find('div',class_ = "comic-body")if comicele == None:print(',无图片')continuecomicele = comicele.find_all('img')[0]#print(comicele)if comicele == []:print('图片未找到')else:comicurl = 'https://xkcd.in/' + comicele.get('src')#res = requests.get(comicurl)name = img_tag.get('alt')print('正在下载:',"D:\\python\\漫画爬虫\\xkcd_2\\%s.png"%(name))urllib.request.urlretrieve(comicurl,"D:\\python\\漫画爬虫\\xkcd_2\\%s.png"%(name))    # urllib.request.urlretrieve函数下载文件。def get_end_id():return int(bs4.BeautifulSoup(requests.get('https://xkcd.in/').text,'html.parser').find('div',class_ = "nextLink").find('a').get('href').split('=')[-1]) + 1def split_(start, end, step):# 分多块parts = [(start, min(start+step, end))for start in range(0, end, step)]return parts
s = split_(1,get_end_id(),50)
for i in s:if not i == s[-1]:d(i[0],i[1])else:d(i[0],i[1] + 1)sleep(5)multitasking.wait_for_tasks()
input('下载完成')

运行结果:

0,无图片
1正在下载: 桶 - 1.png
2正在下载: “小”树(草图).png
50正在下载: Penny Arcade.png
3正在下载: 岛(草图).png
51正在下载: 疟疾.png
524100正在下载: 秘密世界.png
正在下载: 风景(草图).png
正在下载: 激光瞄准镜.png
正在下载: 爱好.png
10254150正在下载: 回到未来.png
正在下载: 科学.png
,无图片
1516,无图片
152正在下载: 冷幽默.png
55103,无图片
153正在下载: 无用功.png
正在下载: 道德相对论.png
56,无图片
1547104正在下载: 解药(治疗乐队).png
正在下载: 睡觉的女孩(素描-高二西班牙语课).png
,无图片
155,无图片

输出很乱,因为有很多线程来输出。不过下得很快,一下子就下完了。

python爬取 XKCD 中文站,包含多线程相关推荐

  1. Python爬取De下载站相关代码

    Python爬取De下载站相关代码,因为没有设置代理,所以爬到800页左右就被干掉了,后续要加上 import urllib.request import bs4 import re import t ...

  2. Python爬取PPT模板(requests+BeautifulSoup+多线程)

    Python爬取PPT模板(requests+BeautifulSoup+多线程) 快到做毕业设计的时间了,得去找点好看的PPT模板了,在http://www.ypppt.com这个网站上发现了很多不 ...

  3. python爬取csdn上的包含整人关键词的阅读量并且存入表格里。完整代码

    请注意,爬取他人网站的数据可能违反网站的条款和条件.在进行爬虫操作之前,请确保获得网站的授权. 下面是一个使用 Python 爬取 CSDN 上所有包含 "整人" 关键词文章的阅读 ...

  4. 用python爬取冰冰B站千条评论,我发现了这些...

    Python爬取 冰冰 第一条B站视频的千条评论,绘制词云图,看看大家说了什么吧 B站当日弹幕获取冰冰B站视频弹幕爬取原理解析 数据分析 import pandas as pd data = pd.r ...

  5. Python 爬取生成中文词云以爬取知乎用户属性为例

    代码如下: # -*- coding:utf-8 -*-import requests import pandas as pd import timeimport matplotlib.pyplot ...

  6. 用python爬取xkcd.com上的有趣漫画图片

    这是自学前端的第二天. 在学<Automate The Boring Stuff With Python>的web开发部分时发现自己对于HTML.CSS等前端标记语言一无所知,于是前两天在 ...

  7. 用python爬取下载b站视频

    B站之所以火,是因为趣味与知识并存.正如一句"你在B站看番,我在B站学习",B站还是有一些质量比较好的学习视频.当你在B站上看到喜欢的视频想保存下来时,怎么办呢? 转入正题,本篇推 ...

  8. 我用Python爬取了“b站弹幕大军,告诉你什么才是真正的“雨女无瓜”

    "网上冲浪""886""GG""沙发"--如果你用过这些,那你可能是7080后: "杯具"" ...

  9. python爬取html中文乱码

    环境: python3.6 爬取网址:https://www.dygod.net/html/tv/hytv/ 爬取代码: import requestsurl = 'https://www.dygod ...

最新文章

  1. apache.camel_Apache Camel 3.1 –更多骆驼核心优化(第3部分)
  2. WX: picker 滚动选择器
  3. 濮阳第二届创客机器人比赛_咸阳市举行第二届机器人大赛暨第一届创客大赛
  4. 天池 在线编程 三等分(模拟)
  5. bp 神经网络 优点 不足_基于粒子群算法和BP神经网络的多因素林火等级预测模型...
  6. MacBook搭建go语言开发环境
  7. 学到了一个一分不亏的地推妙招
  8. LINQ IN ACTION读书笔记:LINQ 使用连接 1、组连接 2、内连接 3、左外连接 4、交叉连接 使用和区别...
  9. 关于Oracle的提示详解(1)
  10. 6N+/-1素数测试法
  11. java栈链_java实现链栈与队列详解
  12. java处理代码表_Java处理中华人民共和国行政区划代码
  13. UML工具大全(上)
  14. python docx创建表格
  15. html实现ppt效果页面,CSS3+JavaScript实现翻页幻灯片效果
  16. Linux free 查看内存使用情况 常用命令
  17. 虚拟邮箱怎么设置方法_商务邮箱一般用什么邮箱正式?VIP邮箱名怎么设置好?...
  18. 基于JAVA干洗店订单管理系统设计与实现计算机毕业设计源码+数据库+lw文档+系统+部署
  19. HihoCoder - 1272 买零食
  20. 舌尖上的职场(二)一起去吃饭吧!(转)

热门文章

  1. 实现一个简单的Java类:长方形与梯形的面积计算
  2. 2022-10-03笔记(内网横向)
  3. Weixin4j微信开发网页授权获取openid案例
  4. SQL优化:Hive---distribute by 防止数据倾斜
  5. Efficient and Effective Data Imputation with Influence Functions
  6. 华为鸿蒙福田办公室,华为鸿蒙第一批名单
  7. 电路设计之--钽电容选取
  8. 读遍装修书,我们帮你选出了最有用的10本
  9. 如何做好创业公司CEO - 量力而行
  10. 使用python切割图片