一、爬虫是什么?
$ Y+ M7 C5 u9 j! |6 u: b 如果我们把互联网比作一张大的蜘蛛网,数据便是存放于蜘蛛网的各个节点,而爬虫就是一只小蜘蛛,沿着网络抓取自己的猎物(数据)爬虫指的是:向网站发起请求,获取资源后分析并提取有用数据的程序;从技术层面来说就是 通过程序模拟浏览器请求站点的行为,把站点返回的HTML代码/JSON数据/二进制数据(图片、视频) 爬到本地,进而提取自己需要的数据,存放起来使用。; z. d# _$ \/ B5 p
二、基本环境配置. ?: ^ Y0 H( y/ H; h2 \5 n
- 版本:Python3
- 系统:Windows
- IDE:Pycharm4 q& g9 f J; q7 v6 p' ` h
三、爬虫所需工具:# \; s, W w, R0 P* f! c/ q
- 请求库:requests,selenium(可以驱动浏览器解析渲染CSS和JS,但有性能劣势(有用没用的网页都会加载);)
- 解析库:正则,beautifulsoup,pyquery
- 存储库:文件,MySQL,Mongodb,Redis
0 c8 L* t) U1 x6 s1 s) i! r 四、Python爬虫基本流程
9 E% S1 ~/ Z* m
, L2 d+ `& [7 A' O8 v8 F" K基础版:+ _. C/ h: @4 A6 M* L3 G: Y
- import re
- import requests
-
- respose = requests.get ('http://www.xiaohuar.com/v/')
- # print(respose.status_code) #响应的状态码
- # print(respose.content) #返回字节信息
- # print(respose.text) #返回文本内容
- urls=re.findall(r'class="items".*?href="(.*?)"',respose.text,re.S) #re.s 把文本信息转换成1行匹配
- url=urls[5]
- result=requests.get(url)
- mp4_url=re.findall(r'id="media".*?src="(.*?)"',result.text,re.s)[0]
-
- video=requests.get(mp4_url)
- with open('D:\\a.mp4,'wb') as f:
- f.write(video.content)
函数封装版:5 N6 _: |2 `8 y5 n7 @) e
- import re
- import requests
- import hashlib
- import time
-
- def get_index(url):
- respose = requests.get(url)
- if respose.status_code==200:
- return respose . text
-
- def parse_index(res):
- urls = re.findall(r'class="itens".*?href="(.*?)"',res,re.S) # re.S 把文本信息转换成1行匹配
- return urls
-
- def get_detail(urls):
- For url in urls
- if not url.startswith('http'):
- url='http://www.xiaohuar.com%s' %url
- result = requests.get(url)
- if result.status_code = 200 :
- mp4_url_list = re.findall(r'id="media".*?src="(.*?)"',result.text,re.S)
- if mp4_url_list:
- mp4_url=mp4_url_list[0]
- print(mp4_url)
- # save mp4_url)
-
- def save(url):
- video = requests.get(url)
- if video.status_code==200:
- m=hashlib.md5()
- m.updata(url.encode('utf-8'))
- m.updata(str(time.time()).encode('utf-8')
- filename=r'%s.mp4'% m.hexdigest()
- filepath=r'D:\\%s'%filename
- with open(filepath,'wb') as f:
- f.write(video.content)
-
- def main():
- for i in range(5):
- res1 = get_index('http://www.xiaohuar.com/list-3-%s.html'% i )
- res2 = parse_index(res1)
- get_detail(res2)
- if __name__ == '__main__':
- main()
并发版
$ j, R4 W5 Z: j* U; ~+ U: Z(如果一共需要爬30个视频,开30个线程去做,花的时间就是其中最慢那份的耗时时间)
7 ~7 L+ J3 r% ~9 [- import re
- import requests
- import hashlib
- import time
- from concurrent.futures import ThreadPoolExecutor
- p=ThreadPoolExecutor(30) #创建1个程池中,容纳线程个数为30个;
-
- def get_index(url):
- respose = requests.get(url)
- if respose.status_code==200:
- respose.text
-
- def parse_index(res):
- res=res.result() #进程执行完毕后,得到1个对象
- urls = re.findall(r'class="items".*?href="(.*?)"',res,re.S) #re.s 把文本信息转换成1行匹配
- for url in urls:
- p.submit(get_detail(url)) #获取详情页 提交到线程池
-
- def get_detail(url): #只下载1个视频
- if not url.startswith('http'):
- url='http://www.xiaohuar.com%s' %url
- result = requests.get(url)
- if result.status_code==200 :
- mp4_url_.findall(r'id="media".*?src="(.*?)"',result.text,re.S)
- if mp4_url_list:
- mp4_url=mp4_url_list[0]
- print(mp4_url)
- # save(mp4_url)
-
- def save(url):
- video = requests.get(url)
- if video.status_code==200:
- m=hashlib.md5()
- m.updata(url.encode('utf-8'))
- m.updata(str(time.time()).encode('utf-8'))
- filename=r'%s.mp4'% m.hexdigest()
- filepath=r'D:\\%s'%filename
- with open(filepath,'wb') as f:
- f.write(video.content)
-
- def main():
- for i in range(5):
- p.submit(get_index,'http://www.xiaohuar.com/list-3-%s.html'% i ).add_done_callback(parse_index)
- #1、先把爬 大牧人任务(get_index)异步提交到线程池
- #2、get_index任务执行完后,会通过回调add_done_callback()通知主线程,任务完成
- #3、把get_index执行结果(注意线程执行结果是对象,调用res=res.result()方法,才能获取真正执行结果),当做参数传给parse_index
- #4、通过循环,再次把获取详情页get_detail()任务提交到线程池执行
-
- if __name__ == '__main__':
- main()
|