妹子图网站—-媒介
从本日最先就要撸起袖子,直接写Python爬虫了,进修言语最好的要领就是有目标的举行,所以,接下来我将用10+篇的博客,写爬图片
这一件事变。愿望能够做好。
为了写好爬虫,我们需要预备一个火狐浏览器,还需要预备抓包东西,抓包东西,我运用的是CentOS自带的tcpdump,加上wireshark ,这两款软件的装置和运用,发起你照样进修一下,背面我们应该会用到。
妹子图网站—- 收集要求模块requests
Python中的大批开源的模块使得编码变的迥殊简朴,我们写爬虫第一个要相识的模块就是requests。
妹子图网站—- 装置requests
翻开终端:运用敕令
pip3 install requests
守候装置终了即可运用
接下来在终端中键入以下敕令
# mkdir demo
# cd demo
# touch down.py
上面的linux敕令是 建立一个名称为demo
的文件夹,今后建立一个down.py
文件,你也能够运用GUI东西,像操纵windows一样,右键建立种种文件。
为了进步在linux上的开辟效力,我们需要装置一个visual studio code
的开辟东西
关于怎样装置vscode,参考官方的https://code.visualstudio.com… 有细致的申明。
关于centos则以下:
sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc sudo sh -c 'echo -e "
\nname=Visual Studio Code\nbaseurl=https://packages.microsoft.com/yumrepos/vscode\nenabled=1\ngpgcheck=1\ngpgkey=https://packages.microsoft.com/keys/microsoft.asc" > /etc/yum.repos.d/vscode.repo'
然后用yum敕令装置
yum check-update sudo yum install code
装置胜利今后,在你的CentOS中会涌现以下画面
接着说我们上面的操纵 ,因为我们这边是用gnome图形界面,所以背面的有些操纵,我直接用windows的操纵作风讲解了
翻开软件>文件>翻开文件>找到我们方才建立的
down.py
文件今后,在VSCODE内里输入
import requests #导入模块 def run(): #声明一个run要领 print("跑码文件") #打印内容 if __name__ == "__main__": #主顺序进口 run() #挪用上面的run要领
tips:本教程不是Python3的基本入门课,所以有些编码基本,默许你懂,比方Python没有分号末端,需要对齐花样。我会只管把解释写的完全
按键盘上的
ctrl+s
保留文件,假如提醒权限不足,那末根据提醒输入暗码即可经由过程终端进入demo目次,然后输入
python3 down.py
显现以下效果,代表编译没有题目
[root@bogon demo]# python3 down.py 跑码文件
接下来,我们最先测试
requests
模块是不是能够运用修正上述代码中的
import requests def run(): response = requests.get("http://www.baidu.com") print(response.text) if __name__ == "__main__": run()
运转效果(涌现下图代表你运转胜利了):
接下来,我们现实下载一张图片尝尝,比以下面这张图片
修正代码,在这之前,我们修正一些内容
因为每次修正文件,都提醒必需管理员权限,所以你能够运用linux敕令修正权限。
[root@bogon linuxboy]# chmod -R 777 demo/
import requests def run(): response = requests.get("http://www.newsimg.cn/big201710leaderreports/xibdj20171030.jpg") with open("a.jpg","wb") as f : f.write(response.content) f.close if __name__ == "__main__": run()
运转代码今后,发如今文件夹内部生成了一个文件
然则翻开文件今后发明,这个文件并不能查阅,这代表这个文件压根没有下载下来
我们继续修正代码,因为有的服务器图片,都做了一些限定,我们能够用浏览器翻开,然则运用Python代码并不能完全的下载下来。
修正代码
import requests def run(): # 头文件,header是字典范例 headers = { "Host":"www.newsimg.cn", "User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.26 Safari/537.36 Core/1.63.5383.400 QQBrowser/10.0.1313.400" } response = requests.get("http://www.newsimg.cn/big201710leaderreports/xibdj20171030.jpg",headers=headers) with open("a.jpg","wb") as f : f.write(response.content) f.close() if __name__ == "__main__": run()
好了,此次在终端编译一下python文件
python3 down.py
发明图片下载下来了
我们重点检察上述代码中
requests.get
部份,增加了一个headers
的实参。如许我们顺序就下载下来了完全的图片。妹子图网站---- Python爬虫页面剖析
有了上面这个简朴的案例,我们接下来的操纵就变的简朴多了。爬虫是怎样举行的呢?
输入域名->下载源代码->剖析图片途径->下载图片
上面就是他的步骤
输入域名
我们本日要爬的网站叫做 http://www.meizitu.com/a/pure...
为啥爬取这个网站,因为好爬。
好了,接下来剖析这个页面
做爬虫很主要的一点,就是你要找到分页的处所,因为有分页代表着有规律,有规律,我们就好爬了(能够做的更智能一些,输入首页网址,爬虫本身就可以剖析到这个网站中的一切地点)
上面图片中,我们发清楚明了分页,那末找规律吧
运用火狐浏览器的开辟者东西,发明分页规律
http://www.meizitu.com/a/pure_1.html http://www.meizitu.com/a/pure_2.html http://www.meizitu.com/a/pure_3.html http://www.meizitu.com/a/pure_4.html
好了,接下来用Python完成这部份(以下写法有部份面向对象的写法,没有基本的同砚,请百度找些基本来看,不过关于想进修的你来讲,这些简朴极了)
import requests all_urls = [] #我们拼接好的图片集和列表途径 class Spider(): #组织函数,初始化数据运用 def __init__(self,target_url,headers): self.target_url = target_url self.headers = headers #猎取一切的想要抓取的URL def getUrls(self,start_page,page_num): global all_urls #轮回获得URL for i in range(start_page,page_num+1): url = self.target_url % i all_urls.append(url) if __name__ == "__main__": headers = { 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0', 'HOST':'www.meizitu.com' } target_url = 'http://www.meizitu.com/a/pure_%d.html' #图片集和列表划定规矩 spider = Spider(target_url,headers) spider.getUrls(1,16) print(all_urls)
上面的代码,能够需要有肯定的Python基本能够看懂,不过你实在细致看一下,就几个要点
第一个是
class Spider():
我们声清楚明了一个类,然后我们运用def __init__
去声明一个组织函数,这些我以为你找个教程30分钟也就学会了。拼接URL,我们能够用许多要领,我这里用的是最直接的,字符串拼接。
注重上述代码中有一个全局的变量
all_urls
我用它来存储我们的一切分页的URL接下来,是爬虫最中心的部份代码了
我们需要剖析页面中的逻辑。起首翻开 http://www.meizitu.com/a/pure... ,右键检察元素。
发明上图赤色框框内里的链接
点击图片今后,发明进入一个图片概况页面,发明竟然是一组图片,那末如今的题目是
我们要处置惩罚第一步,需要在 http://www.meizitu.com/a/pure... 这类页面中爬取一切的 http://www.meizitu.com/a/5585... 这类地点
这里我们采纳多线程的体式格局爬取(这里还用了一种设想形式,叫观察者形式)
import threading #多线程模块 import re #正则表达式模块 import time #时刻模块
起首引入三个模块,离别是多线程,正则表达式,时刻模块
新增添一个全局的变量,而且因为是多线程操纵,我们需要引入线程锁
all_img_urls = [] #图片列表页面的数组 g_lock = threading.Lock() #初始化一个锁
声明一个生产者的类,用来不停的猎取图片概况页地点,然后增加到
all_img_urls
这个全局变量中#生产者,担任从每一个页面提取图片列表链接 class Producer(threading.Thread): def run(self): headers = { 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0', 'HOST':'www.meizitu.com' } global all_urls while len(all_urls) > 0 : g_lock.acquire() #在接见all_urls的时刻,需要运用锁机制 page_url = all_urls.pop() #经由过程pop要领移除末了一个元素,而且返回该值 g_lock.release() #运用完成今后实时把锁给开释,轻易其他线程运用 try: print("剖析"+page_url) response = requests.get(page_url , headers = headers,timeout=3) all_pic_link = re.findall('<a target=\'_blank\' href="(.*?)">',response.text,re.S) global all_img_urls g_lock.acquire() #这里另有一个锁 all_img_urls += all_pic_link #这个处所注重数组的拼接,没有用append直接用的+=也算是python的一个新语法吧 print(all_img_urls) g_lock.release() #开释锁 time.sleep(0.5) except: pass
上述代码用到了继续的观点,我从threading.Thread中继续了一个子类,继续的基本进修,你能够去翻翻 http://www.runoob.com/python3... 菜鸟教程就行。
线程锁,在上面的代码中,当我们操纵
all_urls.pop()
的时刻,我们是不愿望其他线程对他举行同时操纵的,不然会涌现意外,所以我们运用g_lock.acquire()
锁定资本,然后运用完成今后,记着肯定要立马开释g_lock.release()
,不然这个资本就一向被占用着,顺序没法举行下去了。婚配网页中的URL,我运用的是正则表达式,背面我们会运用其他的要领,举行婚配。
re.findall()
要领是猎取一切婚配到的内容,正则表达式,你能够找一个30分钟入门的教程,看看就行。代码轻易失足的处所,我放到了
try: except: 内里,固然,你也能够自定义毛病。
假如上面的代码,都没有题目,那末我们就可以够在顺序进口的处所编写
for x in range(2): t = Producer() t.start()
实行顺序,因为我们的Producer继续自threading.Thread类,所以,你必需要完成的一个要领是
def run
这个我置信在上面的代码中,你已看到了。然后我们能够实行啦~~~运转效果:
如许,图片概况页面的列表就已被我们存储起来了。
接下来,我们需要实行如许一步操纵,我想要守候图片概况页面悉数猎取终了,在举行接下来的剖析操纵。
这里增添代码
#threads= [] #开启两个线程去接见 for x in range(2): t = Producer() t.start() #threads.append(t) # for tt in threads: # tt.join() print("举行到我这里了")
解释症结代码,运转以下
[linuxboy@bogon demo]$ python3 down.py 剖析http://www.meizitu.com/a/pure_2.html 剖析http://www.meizitu.com/a/pure_1.html 举行到我这里了 ['http://www.meizitu.com/a/5585.html',
把上面的tt.join等代码解释翻开
[linuxboy@bogon demo]$ python3 down.py 剖析http://www.meizitu.com/a/pure_2.html 剖析http://www.meizitu.com/a/pure_1.html ['http://www.meizitu.com/a/5429.html', ...... 举行到我这里了
发明一个实质的区分,就是,我们因为是多线程的顺序,所以,当顺序跑起来今后,
print("举行到我这里了")
不会比及其他线程完毕,就会运转到,然则当我们改形成上面的代码今后,也就是加入了症结的代码tt.join()
那末主线程的代码会比及所以子线程运转终了今后,在接着向下运转。这就满足了,我适才说的,先猎取到一切的图片概况页面的鸠合,这一前提了。join所完成的事情就是线程同步,即主线程遇到join今后进入阻塞状态,一向守候其他的子线程实行完毕今后,主线程在继续实行。这个人人在今后能够经常会遇到。
下面编写一个消费者/观察者,也就是不停关注适才我们猎取的那些图片概况页面的数组。
增加一个全局变量,用来存储猎取到的图片链接
pic_links = [] #图片地点列表
#消费者 class Consumer(threading.Thread) : def run(self): headers = { 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0', 'HOST':'www.meizitu.com' } global all_img_urls #挪用全局的图片概况页面的数组 print("%s is running " % threading.current_thread) while len(all_img_urls) >0 : g_lock.acquire() img_url = all_img_urls.pop() g_lock.release() try: response = requests.get(img_url , headers = headers ) response.encoding='gb2312' #因为我们挪用的页面编码是GB2312,所以需要设置一下编码 title = re.search('<title>(.*?) | 妹子图</title>',response.text).group(1) all_pic_src = re.findall('<img alt=.*?src="(.*?)" /><br />',response.text,re.S) pic_dict = {title:all_pic_src} #python字典 global pic_links g_lock.acquire() pic_links.append(pic_dict) #字典数组 print(title+" 猎取胜利") g_lock.release() except: pass time.sleep(0.5)
看到没有,上面的代码实在和我们适才写的极为类似,背面,我会在github上面把这部份代码修正的越发简约一些,不过这才是第二课,背面我们的路长着呢。
代码中比较主要的一些部份,我已运用解释写好了,人人能够直接参考。人人肯定要注重我上面运用了两个正则表达式,离别用来婚配title和图片的url这个title是为了背面建立差别的文件夹运用的,所以人人注重吧。
#开启10个线程去猎取链接 for x in range(10): ta = Consumer() ta.start()
运转效果:
[linuxboy@bogon demo]$ python3 down.py 剖析http://www.meizitu.com/a/pure_2.html 剖析http://www.meizitu.com/a/pure_1.html ['http://www.meizitu.com/a/5585.html', ...... <function current_thread at 0x7f7caef851e0> is running <function current_thread at 0x7f7caef851e0> is running <function current_thread at 0x7f7caef851e0> is running <function current_thread at 0x7f7caef851e0> is running <function current_thread at 0x7f7caef851e0> is running <function current_thread at 0x7f7caef851e0> is running <function current_thread at 0x7f7caef851e0> is running <function current_thread at 0x7f7caef851e0> is running 举行到我这里了 <function current_thread at 0x7f7caef851e0> is running <function current_thread at 0x7f7caef851e0> is running 纯洁美如画,摄影师的御用麻豆 猎取胜利 宅男女神恭弘=叶 恭弘梓萱近日拍摄一组火爆写真 猎取胜利 美(bao)胸(ru)女王带来礼服引诱 猎取胜利 天天睁开眼看到优美的你,就是幸运 猎取胜利 可爱女孩,愿暖风庇护单纯和固执 猎取胜利 纯洁妹子如一缕阳光暖和这个冬季 猎取胜利 .....
是不是是觉得间隔胜利有进了一大步
接下来就是,我们开篇提到的谁人存储图片的操纵了,照样一样的步骤,写一个自定义的类
class DownPic(threading.Thread) : def run(self): headers = { 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0', 'HOST':'mm.chinasareview.com' } while True: # 这个处所写成死轮回,为的是不停监控图片链接数组是不是更新 global pic_links # 上锁 g_lock.acquire() if len(pic_links) == 0: #假如没有图片了,就解锁 # 不论什么情况,都要开释锁 g_lock.release() continue else: pic = pic_links.pop() g_lock.release() # 遍历字典列表 for key,values in pic.items(): path=key.rstrip("\\") is_exists=os.path.exists(path) # 推断效果 if not is_exists: # 假如不存在则建立目次 # 建立目次操纵函数 os.makedirs(path) print (path+'目次建立胜利') else: # 假如目次存在则不建立,并提醒目次已存在 print(path+' 目次已存在') for pic in values : filename = path+"/"+pic.split('/')[-1] if os.path.exists(filename): continue else: response = requests.get(pic,headers=headers) with open(filename,'wb') as f : f.write(response.content) f.close
我们猎取图片链接今后,就需要下载了,我上面的代码是起首建立了一个之前猎取到
title
的文件目次,然后在目次内里经由过程下面的代码,去建立一个文件。涉及到文件操纵,引入一个新的模块
import os #目次操纵模块
# 遍历字典列表 for key,values in pic.items(): path=key.rstrip("\\") is_exists=os.path.exists(path) # 推断效果 if not is_exists: # 假如不存在则建立目次 # 建立目次操纵函数 os.makedirs(path) print (path+'目次建立胜利') else: # 假如目次存在则不建立,并提醒目次已存在 print(path+' 目次已存在') for pic in values : filename = path+"/"+pic.split('/')[-1] if os.path.exists(filename): continue else: response = requests.get(pic,headers=headers) with open(filename,'wb') as f : f.write(response.content) f.close
因为我们的图片链接数组,内里寄存是的字典花样,也就是下面这类花样
[{"妹子图1":["http://mm.chinasareview.com/wp-content/uploads/2016a/08/24/01.jpg","http://mm.chinasareview.com/wp-content/uploads/2016a/08/24/02.jpg"."http://mm.chinasareview.com/wp-content/uploads/2016a/08/24/03.jpg"]},{"妹子图2":["http://mm.chinasareview.com/wp-content/uploads/2016a/08/24/01.jpg","http://mm.chinasareview.com/wp-content/uploads/2016a/08/24/02.jpg"."http://mm.chinasareview.com/wp-content/uploads/2016a/08/24/03.jpg"]},{"妹子图3":["http://mm.chinasareview.com/wp-content/uploads/2016a/08/24/01.jpg","http://mm.chinasareview.com/wp-content/uploads/2016a/08/24/02.jpg"."http://mm.chinasareview.com/wp-content/uploads/2016a/08/24/03.jpg"]}]
需要先轮回第一层,猎取title,建立目次今后,在轮回第二层去下载图片,代码中,我们在修正一下,把非常处置惩罚增加上。
try: response = requests.get(pic,headers=headers) with open(filename,'wb') as f : f.write(response.content) f.close except Exception as e: print(e) pass
然后在主顺序中编写代码
#开启10个线程保留图片 for x in range(10): down = DownPic() down.start()
运转效果:
[linuxboy@bogon demo]$ python3 down.py 剖析http://www.meizitu.com/a/pure_2.html 剖析http://www.meizitu.com/a/pure_1.html ['http://www.meizitu.com/a/5585.html', 'http://www.meizitu.com/a/5577.html', 'http://www.meizitu.com/a/5576.html', 'http://www.meizitu.com/a/5574.html', 'http://www.meizitu.com/a/5569.html', ....... <function current_thread at 0x7fa5121f2268> is running <function current_thread at 0x7fa5121f2268> is running <function current_thread at 0x7fa5121f2268> is running 举行到我这里了 纯洁妹子如一缕阳光暖和这个冬季 猎取胜利 纯洁妹子如一缕阳光暖和这个冬季目次建立胜利 可爱女孩,愿暖风庇护单纯和固执 猎取胜利 可爱女孩,愿暖风庇护单纯和固执目次建立胜利 超美,纯纯的你与蓝蓝的天相得益彰 猎取胜利 超美,纯纯的你与蓝蓝的天相得益彰目次建立胜利 优美冻人,雪地里的跆拳道少女 猎取胜利 五官细腻的美眉,似乎童话里的公主 猎取胜利 有自信诱人的笑颜,天天都是绚烂的 猎取胜利 五官细腻的美眉,似乎童话里的公主目次建立胜利 有自信诱人的笑颜,天天都是绚烂的目次建立胜利 纯洁美如画,摄影师的御用麻豆 猎取胜利
文件目次下面同时涌现
点开一个目次
好了,本日的一个简朴的爬虫成了
末了我们在代码的头部写上
# -*- coding: UTF-8 -*-
防备涌现
Non-ASCII character 'xe5' in file
报错题目。迎接关注「非本科顺序员」 复兴 【妹子图】猎取资本