爬虫

爬虫本质就是模拟浏览器访问

所以理论上平时网页中的操作都可以使用爬虫技术来复原操作

在熟悉HTTP的基础上,可以说是很简单的

爬虫的步骤

1、分析网页

通过F12查看并分析页面,找到需要的数据

如果数据是由JS获得的,就需要使用phantomjs(无头浏览器),selenium(驱动浏览器进行访问)

2、爬取页面

把需要的页面下载下来,解析,得到数据

涉及库:requests(构造访问请求),BeautifulSoup(解析DOM,变成python对象)

3、保存数据

将下载下来的数据保存到本地,数据库、表格、文件

4、分析数据

使用各种库分析数据,生成报表

源码:

 设置header属性,User-agent和Referer(通常使用网站主页),模仿浏览器的行为

 设置cookies进行session保持,登陆操作基本都会涉及

 1 #coding:utf8
 2 import requests
 3 
 4 index_url = 'https://dig.chouti.com/'
 5 login_url = 'https://dig.chouti.com/login'
 6 dianzan_url = 'https://dig.chouti.com/link/vote?linksId=19715301'
 7 
 8 header = {
 9     'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36',
10 }
11 
12 form_data = {
13     'phone':'username',
14     'password':'password',
15     'oneMonth':'1',
16 }
17 
18 #创建session对象,发送请求时会携带cookies
19 s = requests.session()
20 #访问首页
21 s.get(index_url,headers = header)
22 #登陆
23 s.post(login_url,form_data,headers = header)
24 #点赞
25 rep = s.post(dianzan_url,'',headers=header)
26 #打印结果
27 print(rep.text)
28 #{"result":{"code":"9999", "message":"推荐成功", "data":{"jid":"cdu_51850864329","likedTime":"1526978335436000"
29 # ,"lvCount":"10","nick":"Flask","uvCount":"5","voteTime":"小于1分钟前"}}}
模拟登陆抽屉并点赞

自动翻页爬取

 1 #coding:utf8
 2 import requests
 3 from bs4 import BeautifulSoup
 4 import time
 5 
 6 #多线程爬虫,但没有设置线程数量上限,当页面过多时会消耗过多资源
 7 #定义page集合,为了去重
 8 page_set = set()
 9 
10 def get_page(url):
11     global page_set
12     header = {
13         'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36',
14     }
15     rep = requests.get('http://www.521609.com/daxuexiaohua'+url, headers=header)
16     soup = BeautifulSoup(rep.text, 'lxml')
17     #找到图片,并找到其img_url
18     imgs = soup.select('.index_img ul a img')
19     for img in imgs:
20         img_url = 'http://www.521609.com' + img.get_attribute_list('src')[0]
21         print('下载图片%s'%img_url)
22     #找到别的页面
23     pages = soup.select('.index_img .listpage a')
24     for page in pages:
25         page_url = '/' + page.get_attribute_list('href')[0]
26         #不是重复页面则访问
27         if page_url not in page_set:
28             page_set.add(page_url)
29             print('正在访问%s' % page_url)
30             #无限递归访问
31             get_page(page_url)
32 
33 time_start=time.time()
34 get_page('')
35 time_end=time.time()
36 print('共耗时:%s秒'%(time_end-time_start))
37 #共耗时:43.121999979秒
爬取校花网照片

多线程貌似会莫名名气的卡死,特别的线程池卡死情况更严重

 1 #coding:utf8
 2 import threading
 3 import requests
 4 from bs4 import BeautifulSoup
 5 import time
 6 
 7 #多线程爬虫,但没有设置线程数量上限,当页面过多时会消耗过多资源
 8 #定义page集合,为了去重
 9 page_set = set()
10 lock = threading.Lock()
11 
12 def get_page(url):
13     global page_set
14     header = {
15         'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36',
16     }
17     rep = requests.get('http://www.521609.com/daxuexiaohua'+url, headers=header)
18     soup = BeautifulSoup(rep.text, 'lxml')
19     #找到图片,并找到其img_url
20     imgs = soup.select('.index_img ul a img')
21     for img in imgs:
22         img_url = 'http://www.521609.com' + img.get_attribute_list('src')[0]
23         #在资源抢占的地方加锁
24         lock.acquire()
25         print('下载图片%s'%img_url)
26         lock.release()
27     #找到别的页面
28     pages = soup.select('.index_img .listpage a')
29     t_list=[]
30     for page in pages:
31         page_url = '/' + page.get_attribute_list('href')[0]
32         #不是重复页面则访问
33         if page_url not in page_set:
34             page_set.add(page_url)
35             lock.acquire()
36             f = open('qq.txt','a+')
37             f.write('正在访问%s
' % page_url)
38             f.close()
39             print('正在访问%s' % page_url)
40             lock.release()
41             #无限递归访问
42             #每一次页面访问就开一个线程
43             task = threading.Thread(target=get_page, args=(page_url,))
44             task.start()
45             t_list.append(task)
46     for t in t_list:
47         t.join()
48 
49 
50 time_start=time.time()
51 get_page('')
52 time_end=time.time()
53 print('共耗时:%s秒'%(time_end-time_start))
54 #共耗时:4.117000103秒
多线程爬取校花网照片

推荐使用,开销小,配置简单

 1 from gevent import monkey
 2 monkey.patch_all()
 3 from gevent.pool import Pool
 4 import gevent
 5 import requests
 6 from bs4 import BeautifulSoup
 7 import time
 8 
 9 #协程的方式
10 #定义page集合,为了去重
11 page_set = set()
12 
13 
14 def get_page(url):
15     global page_set
16     header = {
17         'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36',
18     }
19     rep = requests.get('http://www.521609.com/daxuexiaohua'+url, headers=header)
20     soup = BeautifulSoup(rep.text, 'lxml')
21     #找到图片,并找到其img_url
22     imgs = soup.select('.index_img ul a img')
23     for img in imgs:
24         img_url = 'http://www.521609.com' + img.get_attribute_list('src')[0]
25         #在资源抢占的地方加锁
26         print('下载图片%s'%img_url)
27     #找到别的页面
28     pages = soup.select('.index_img .listpage a')
29     g_list=[]
30     for page in pages:
31         page_url = '/' + page.get_attribute_list('href')[0]
32         #不是重复页面则访问
33         if page_url not in page_set:
34             page_set.add(page_url)
35             print('正在访问%s' % page_url)
36             #无限递归访问
37             #每一次页面访问就开一个线程
38             g = gevent.spawn(get_page,page_url)
39             g_list.append(g)
40     for g1 in g_list:
41         g1.join()
42 
43 
44 time_start=time.time()
45 get_page('')
46 time_end=time.time()
47 print('共耗时:%s秒'%(time_end-time_start))
48 #共耗时:4.104735612869263秒
协程(gevent)爬取校花网照片

保存数据到no-sql数据库redis

爬虫爬到的数据一般不是结构化的,使用key-value的方式保存更合适,而且更快

 1 #coding:utf8
 2 from gevent import monkey
 3 monkey.patch_all()
 4 import gevent
 5 import requests
 6 from bs4 import BeautifulSoup
 7 import time
 8 import redis
 9 
10 
11 #协程的方式,存储数据到redis
12 #定义page集合,为了去重
13 page_set = set()
14 
15 def get_page(url):
16     global page_set
17     header = {
18         'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36',
19     }
20     rep = requests.get('http://www.521609.com/daxuexiaohua'+url, headers=header)
21     soup = BeautifulSoup(rep.text, 'lxml')
22     #找到图片,并找到其img_url
23     imgs = soup.select('.index_img ul a img')
24     #连接redis
25     r = redis.Redis(host='127.0.0.1', port='6379')
26     for img in imgs:
27         img_url = 'http://www.521609.com' + img.get_attribute_list('src')[0]
28         img_name = img.get_attribute_list('alt')[0]
29         #储存数据到redis,图片名是key,url是value
30         r.set(img_name,img_url)
31         print('下载图片%s'%img_url)
32     #保存到redis
33     r.save()
34     #找到别的页面
35     pages = soup.select('.index_img .listpage a')
36     g_list=[]
37     for page in pages:
38         page_url = '/' + page.get_attribute_list('href')[0]
39         #不是重复页面则访问
40         if page_url not in page_set:
41             page_set.add(page_url)
42             print('正在访问%s' % page_url)
43             #无限递归访问
44             #每一次页面访问就开一个协程
45             g = gevent.spawn(get_page,page_url)
46             g_list.append(g)
47     for g1 in g_list:
48         g1.join()
49 
50 
51 time_start=time.time()
52 get_page('')
53 time_end=time.time()
54 print('共耗时:%s秒'%(time_end-time_start))
55 #共耗时:13.4720001221秒
56 #由于有了数据库的I/O,时间变长了
协程爬取校花网照片并保存到redis
原文地址:https://www.cnblogs.com/cx59244405/p/9064574.html