zoukankan      html  css  js  c++  java
  • 爬虫

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

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

    在熟悉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
  • 相关阅读:
    vsftpd文件服务参数汇总和虚拟用户使用
    MHA实现mysql高可用复制集群
    mysqldump备份与基于bin-log实现完全恢复
    MySQL的日志相关内容
    MySQL(mariadb)主从复制模式与复制过滤
    MySQL(mariadb)多实例应用与多实例主从复制
    DNS的主从,转发与负载功能
    Spring 自动代理
    Jquery Validate 使用记坑
    动态代理
  • 原文地址:https://www.cnblogs.com/cx59244405/p/9064574.html
Copyright © 2011-2022 走看看