上期,我们获取了每一本书的链接,现在我们要做的工作就很简单了,只需把每个网页上的图片下载下来即可。源代码原文,提取码tt19
/1.获取图片/
根据上期讲的正则表达式,我们看可以根据下图写出表达式:
<img .*? src="(.*?)" .*?>
之所以选择src而不是src是因为根据我的经验,src属性有些时候会给你一下子吞掉,所以选用src比较保险。
还有一个要特别提醒的地方就是一定要注意空格的使用,比如说上节课:
<a .*? href="(.*?)" .*? data-linktype="1".*?><a .*? href="(.*?)" .*? data-linktype="1" .*?>
看出来有什么区别了吗?有些时候,第一个就能匹配出,而第二个不行,因为他在最后用了一个空格,而有些时候data-linktype是最后一个参数,他就正好识别不出。
完整代码:
def get_pic(url): print('crawling pic') headers = {'user-agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Mobile Safari/537.36'} r = requests.get(url,headers=headers) pics = re.findall(r'',r.text) return pics
即获取一个url里的所有图片地址。
/2.保存图片/
我们是通过dirname这个列表来实现的,当然,你也可以试试用年级版本科目来组合,但是经过测试,这才是最简单的:
def save_pic(url,dirname,name): urlretrieve(url,'教材\\'+dirname+'\\'+name+'.png')def main(): headers = {'user-agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Mobile Safari/537.36'} r = requests.get('https://mp.weixin.qq.com/s/ch0O7E4ToDjGEpWenGKQEg',headers = headers) hrefs = [x for x in re.findall(r'',r.text)] dir_names = ['部编版语文一年级下', '部编版语文二年级下', '部编版语文三年级下', '部编版语文四年级下', '部编版语文五年级下', '部编版语文六年级下', '部编版语文七年级下', '部编版语文八年级下', '部编版语文九年级下', '人教版数学一年级下', '人教版数学二年级下', '人教版数学三年级下', '人教版数学四年级下', '人教版数学五年级下', '人教版数学六年级下', '北师大版数学一年级下', '北师大版数学二年级下', '北师大版数学三年级下', '北师大版数学四年级下', '北师大版数学五年级下', '北师大版数学六年级下', '苏教版数学一年级下', '苏教版数学二年级下', '苏教版数学三年级下', '苏教版数学四年级下', '苏教版数学五年级下', '苏教版数学六年级下'] try: os.mkdir('教材') except: pass for d in range(len(dir_names)): h = get_pic(hrefs[d]) try: os.mkdir('教材\\'+dir_names[d]) except: pass for img in range(len(h)): save_pic(h[img],dir_names[d],str(img)) print('save_fine:'+dir_names[d]+' '+str(img)) time.sleep(0.8) print('finish'+dir_names[d])
这个代码的逻辑非常简单,谁都能看懂,不作讲解
/3.拓展:代理ip爬取/
你如果是第一次就成功爬取,那应该没啥问题,但是如果你像我一样一次一次调试出来的,就会发现...
ConnectionResetError: [WinError 10054] 远程主机强迫关闭了一个现有的连接。
没错他报错了,那他为什么会报错呢?
其实在反 反 爬 虫 秘 术里讲到过,这就是ip被一步一步封掉了。
那该怎么办呢?有几个办法:
1.手动代理ip爬取,建一个ip池,每次超时后更换ip。
2.动态拨号服务器
这里主要讲解第一种方法,即手动代理ip。
其实很简单,只要把ip以协议://ip:端口的形式填在一个字典里,最后把这个字典传给requests就好了。
实战一下:
proxies = {'http':'http://125.123.159.254:3000'}r = requests.get('xxxx',proxies=proxies)
这样就可以代理ip爬取了,在源代码里没有提供,请读者自行实验
那么有人会问了:“哪里来的ip呢?”
推荐一个网站:https://www.xicidaili.com/有很多代理ip,但不一定都有用,可以去网上看看“代理ip池”的文章。
今天你学废了吗?