zoukankan      html  css  js  c++  java
  • Python爬虫:设置Cookie解决网站拦截并爬取蚂蚁短租

    前言

    文的文字及图片来源于网络,仅供学习、交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理。

    作者: Eastmount

    PS:如有需要Python学习资料的小伙伴可以加点击下方链接自行获取

    http://note.youdao.com/noteshare?id=3054cce4add8a909e784ad934f956cef

    我们在编写Python爬虫时,有时会遇到网站拒绝访问等反爬手段,比如这么我们想爬取蚂蚁短租数据,它则会提示“当前访问疑似黑客攻击,已被网站管理员设置为拦截”提示,如下图所示。此时我们需要采用设置Cookie来进行爬取,下面我们进行详细介绍。非常感谢我的学生承峰提供的思想,后浪推前浪啊!

    一. 网站分析与爬虫拦截

    当我们打开蚂蚁短租搜索贵阳市,反馈如下图所示结果。 在这里插入图片描述 我们可以看到短租房信息呈现一定规律分布,如下图所示,这也是我们要爬取的信息。 在这里插入图片描述

    通过浏览器审查元素,我们可以看到需要爬取每条租房信息都位于<dd></dd>节点下。 在这里插入图片描述 在定位房屋名称,如下图所示,位于<div class="room-detail clearfloat"></div>节点下。 在这里插入图片描述

    接下来我们写个简单的BeautifulSoup进行爬取。

     1 # -*- coding: utf-8 -*-
     2 import urllib
     3 import re 
     4 from bs4 import BeautifulSoup
     5 import codecs
     6  
     7 url = 'http://www.mayi.com/guiyang/?map=no'
     8 response=urllib.urlopen(url)
     9 contents = response.read()
    10 soup = BeautifulSoup(contents, "html.parser")
    11 print soup.title
    12 print soup
    13 #短租房名称
    14 for tag in soup.find_all('dd'):
    15     for name in tag.find_all(attrs={"class":"room-detail clearfloat"}):
    16         fname = name.find('p').get_text()
    17         print u'[短租房名称]', fname.replace('
    ','').strip()

    但很遗憾,报错了,说明蚂蚁金服防范措施还是挺到位的。 在这里插入图片描述

    二. 设置Cookie的BeautifulSoup爬虫

    添加消息头的代码如下所示,这里先给出代码和结果,再教大家如何获取Cookie。

     1 # -*- coding: utf-8 -*-
     2 import urllib2
     3 import re 
     4 from bs4 import BeautifulSoup
     5  
     6  
     7 #爬虫函数
     8 def gydzf(url):
     9     user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36"
    10     headers={"User-Agent":user_agent}
    11     request=urllib2.Request(url,headers=headers)
    12     response=urllib2.urlopen(request)
    13     contents = response.read() 
    14     soup = BeautifulSoup(contents, "html.parser")
    15     for tag in soup.find_all('dd'):
    16         #短租房名称
    17         for name in tag.find_all(attrs={"class":"room-detail clearfloat"}):
    18             fname = name.find('p').get_text()
    19             print u'[短租房名称]', fname.replace('
    ','').strip()
    20         #短租房价格
    21         for price in tag.find_all(attrs={"class":"moy-b"}):
    22             string = price.find('p').get_text()
    23             fprice = re.sub("[¥]+".decode("utf8"), "".decode("utf8"),string)
    24             fprice = fprice[0:5]
    25             print u'[短租房价格]', fprice.replace('
    ','').strip()
    26             #评分及评论人数
    27             for score in name.find('ul'):
    28                 fscore = name.find('ul').get_text()
    29             print u'[短租房评分/评论/居住人数]', fscore.replace('
    ','').strip()           
    30             #网页链接url           
    31             url_dzf = tag.find(attrs={"target":"_blank"})
    32             urls = url_dzf.attrs['href']
    33             print u'[网页链接]', urls.replace('
    ','').strip()
    34             urlss = 'http://www.mayi.com' + urls + ''
    35             print urlss
    36  
    37 #主函数
    38 if __name__ == '__main__':
    39     i = 1
    40     while i<10:
    41         print u'页码', i
    42         url = 'http://www.mayi.com/guiyang/' + str(i) + '/?map=no'
    43         gydzf(url)
    44         i = i+1
    45     else:
    46         print u"结束"

    输出结果如下图所示:

     1 页码 1
     2 [短租房名称] 大唐东原财富广场--城市简约复式民宿
     3 [短租房价格] 298
     4 [短租房评分/评论/居住人数] 5.0分·5条评论·二居·可住3人
     5 [网页链接] /room/851634765
     6 http://www.mayi.com/room/851634765
     7 [短租房名称] 大唐东原财富广场--清新柠檬复式民宿
     8 [短租房价格] 568
     9 [短租房评分/评论/居住人数] 2条评论·三居·可住6人
    10 [网页链接] /room/851634467
    11 http://www.mayi.com/room/851634467
    12  
    13 ...
    14  
    15 页码 9
    16 [短租房名称] 【高铁北站公园旁】美式风情+超大舒适安逸
    17 [短租房价格] 366
    18 [短租房评分/评论/居住人数] 3条评论·二居·可住5人
    19 [网页链接] /room/851018852
    20 http://www.mayi.com/room/851018852
    21 [短租房名称] 大营坡(中大国际购物中心附近)北欧小清新三室
    22 [短租房价格] 298
    23 [短租房评分/评论/居住人数] 三居·可住6人
    24 [网页链接] /room/851647045
    25 http://www.mayi.com/room/851647045

    在这里插入图片描述

    接下来我们想获取详细信息 在这里插入图片描述

    这里作者主要是提供分析Cookie的方法,使用浏览器打开网页,右键“检查”,然后再刷新网页。在“NetWork”中找到网页并点击,在弹出来的Headers中就隐藏这这些信息。 在这里插入图片描述

    最常见的两个参数是Cookie和User-Agent,如下图所示:

    在这里插入图片描述

    然后在Python代码中设置这些参数,再调用Urllib2.Request()提交请求即可,核心代码如下:

    1   user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) ... Chrome/61.0.3163.100 Safari/537.36"
    2   cookie="mediav=%7B%22eid%22%3A%22387123...b3574ef2-21b9-11e8-b39c-1bc4029c43b8"
    3   headers={"User-Agent":user_agent,"Cookie":cookie}
    4   request=urllib2.Request(url,headers=headers)
    5   response=urllib2.urlopen(request)
    6   contents = response.read() 
    7   soup = BeautifulSoup(contents, "html.parser")
    8   for tag1 in soup.find_all(attrs={"class":"main"}):    

    注意,每小时Cookie会更新一次,我们需要手动修改Cookie值即可,就是上面代码的cookie变量和user_agent变量。完整代码如下所示:

     1 import urllib2 
     2 import re 
     3 from bs4 import BeautifulSoup
     4 import codecs
     5 import csv
     6  
     7  
     8 c = open("ycf.csv","wb") #write 写
     9 c.write(codecs.BOM_UTF8)
    10 writer = csv.writer(c)
    11 writer.writerow(["短租房名称","地址","价格","评分","可住人数","人均价格"])
    12  
    13  
    14 #爬取详细信息
    15 def getInfo(url,fname,fprice,fscore,users):
    16     #通过浏览器开发者模式查看访问使用的user_agent及cookie设置访问头(headers)避免反爬虫,且每隔一段时间运行要根据开发者中的cookie更改代码中的cookie
    17     user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36"
    18     cookie="mediav=%7B%22eid%22%3A%22387123%22eb7; mayi_uuid=1582009990674274976491; sid=42200298656434922.85.130.130"
    19     headers={"User-Agent":user_agent,"Cookie":cookie}
    20     request=urllib2.Request(url,headers=headers)
    21     response=urllib2.urlopen(request)
    22     contents = response.read() 
    23     soup = BeautifulSoup(contents, "html.parser")
    24     #短租房地址
    25     for tag1 in soup.find_all(attrs={"class":"main"}):    
    26         print u'短租房地址:'
    27         for tag2 in tag1.find_all(attrs={"class":"desWord"}):
    28             address = tag2.find('p').get_text()
    29             print address
    30     #可住人数     
    31         print u'可住人数:'
    32         for tag4 in tag1.find_all(attrs={"class":"w258"}):
    33             yy = tag4.find('span').get_text()
    34             print yy
    35         fname = fname.encode("utf-8")
    36         address = address.encode("utf-8")
    37         fprice = fprice.encode("utf-8")
    38         fscore = fscore.encode("utf-8")
    39         fpeople = yy[2:3].encode("utf-8")
    40         ones = int(float(fprice))/int(float(fpeople))
    41         #存储至本地
    42         writer.writerow([fname,address,fprice,fscore,fpeople,ones])
    43     
    44  
    45 #爬虫函数
    46 def gydzf(url):
    47     user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36"
    48     headers={"User-Agent":user_agent}
    49     request=urllib2.Request(url,headers=headers)
    50     response=urllib2.urlopen(request)
    51     contents = response.read() 
    52     soup = BeautifulSoup(contents, "html.parser")
    53     for tag in soup.find_all('dd'):
    54     #短租房名称
    55         for name in tag.find_all(attrs={"class":"room-detail clearfloat"}):
    56             fname = name.find('p').get_text()
    57             print u'[短租房名称]', fname.replace('
    ','').strip()
    58     #短租房价格
    59         for price in tag.find_all(attrs={"class":"moy-b"}):
    60             string = price.find('p').get_text()
    61             fprice = re.sub("[¥]+".decode("utf8"), "".decode("utf8"),string)
    62             fprice = fprice[0:5]
    63             print u'[短租房价格]', fprice.replace('
    ','').strip()
    64     #评分及评论人数
    65             for score in name.find('ul'):
    66                 fscore = name.find('ul').get_text()
    67             print u'[短租房评分/评论/居住人数]', fscore.replace('
    ','').strip()           
    68    #网页链接url           
    69             url_dzf = tag.find(attrs={"target":"_blank"})
    70             urls = url_dzf.attrs['href']
    71             print u'[网页链接]', urls.replace('
    ','').strip()
    72             urlss = 'http://www.mayi.com' + urls + ''
    73             print urlss
    74             getInfo(urlss,fname,fprice,fscore,user_agent)
    75       
    76 #主函数
    77 if __name__ == '__main__':    
    78     i = 0
    79     while i<33:
    80         print u'页码', (i+1)
    81         if(i==0):
    82             url = 'http://www.mayi.com/guiyang/?map=no'
    83         if(i>0):
    84             num = i+2 #除了第一页是空的,第二页开始按2顺序递增
    85             url = 'http://www.mayi.com/guiyang/' + str(num) + '/?map=no'
    86         gydzf(url)
    87         i=i+1
    88  
    89 c.close()

    输出结果如下,存储本地CSV文件:

    在这里插入图片描述

    同时,大家可以尝试Selenium爬取蚂蚁短租,应该也是可行的方法。最后希望文章对您有所帮助,如果存在不足之处,请海涵~

  • 相关阅读:
    【复现】cve-2020-1472 微软NetLogon权限提升漏洞 附exp
    Vmware 问题【持续更新】
    linux命令之上传文件和下载文件-lrzsz
    在ubuntu16.04中输入不存在shell命令时,报错ModuleNotFoundError的解决方案
    linux编译命令:tmpfs,make,distcc,ccache
    Linux常用命令之必知必会
    crontab定时任务
    Ubuntu使用官网的安装包安装Nodejs
    接口测试(Python)之DDT
    【XMCTF】web3 考核
  • 原文地址:https://www.cnblogs.com/Qqun821460695/p/11918533.html
Copyright © 2011-2022 走看看