实战反爬虫

  • 2019 年 10 月 5 日
  • 筆記

python爬虫系列之Senium反爬虫

0.说在前面1.反爬虫方案2.实现 2.1 导库 2.2 selenium 2.3 BS处理图片3.作者的话

0.说在前面

本周更新了机器学习,leetcode以及知识图谱,可视化的文章,还差爬虫,那么今天来实战一波!让各位爬虫伙伴久等了!

1.反爬虫方案

说在前面:爬取的是国家地理中文网上最新一栏的三张图片,点击查看更多又会出现三张图片,总共六张。

第一个难点:获取真实的html

  • selenium + chromdriver

通过url直接访问这个网站,获得的html并不是想要的,会发现里面提示: 浏览器正在安全检查中….

对于上述并未爬到想要的html解决方案是,发现该网站通过js来运行,倒计时后将字符串拼接请求,进入相应网站,如果能够模拟浏览器自动执行js,那么就实现了我们想要的效果了。

于是,这里采用selenium通过chromdriver调用chrome浏览器,模拟操作,自动运行js,(这里注意,倒计时5s,那么get url后,设置时间得大于5s,用time模块的sleep方法模拟即可)进而直接获得相应的html,随后进行正常的爬虫。

第二个难点:获得html后,并通BeautifulSoup获取到了6张图片的url,如何下载url对应的图片

  • requests.get + cookies + headers

这里下载采用requests.get方法来下载图片,但是直接这样操作会出现503错误(Service Unavailable),下载出来的图片也无法查看,那么就要解决这个问题。 解决办法:通过webdriver获得cookies,并对cookie进行下载与格式化为字典形式,传递给requests的get方法,除此之外,需要将User-Agent传递给requests的get方法,这里写入headers中进行传递。

第三个难点:如何将这些下载的图片进行呈现,并合并到一张图中集体展示

  • matplotlib.pyplot + matplotlib.image

先通过matplotlib.image的imread方法读取图片,再通过matplotlib.pyplot绘制一个figure,然后在绘制子图放入figure中即可。

2.实现

2.1 导库

import time  from bs4 import BeautifulSoup as bs  from selenium import webdriver  import requests  import matplotlib.pyplot as plt  import matplotlib.image as mping  

2.2 selenium

# 反爬虫应对代码    driver = webdriver.Chrome() #注意需要将chromedriver放入代码中方可运行  URL = 'http://www.ngchina.com.cn/animals/'  driver.get(URL)  time.sleep(7) # 要大于5s  html=driver.page_source # 获取实际页面的html  # print(html)  

2.3 BS处理图片

保存下载cookies操作

# 获取cookies,保存到本地,读取进行格式化  driver_cookie = driver.get_cookies()  cookies = [item["name"] + "=" + item["value"] for item in driver_cookie]  cookiesStr = ' '.join(cookies)  # print cookiesStr  with open('cookies.txt', 'w') as f:      f.write(cookiesStr)    with open('cookies.txt') as f:      str_cookies = f.read()  print("str_cookies..................."+str_cookies)  list_cookies = str_cookies.split(' ')  # 对字符串切片,返回分割后的字符串列表    cookies = {}  for cookie in list_cookies:      '''      robots=1      cookie.split('=')      变为      ['robots', '1']      key = cookie.split('=')[0]      value = cookie.split('=')[-1]      '''      key = cookie.split('=')[0]      value = cookie.split('=')[-1]      '''      dict.update(dict2)      # 把字典dict2的键/值对更新到dict里      '''      cookies.update({key : value}) # 变为字典类型,如:{'robots': '1'}  print(cookies)  

BeautifulSoup根据真实Html,获取图片Url

soup = bs(html,'lxml')  img_ul = soup.find_all('ul',{"class":"img_list"})  print(img_ul)      headers = {  'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36',  }    i=1  for ul in img_ul:      imgs = ul.find_all('img')      for img in imgs:          url = img['src']            r = requests.get(url, headers=headers, cookies=cookies) # cookies与headers一起解决503错误          print(r.status_code)          image_name = url.split('/')[-1]          with open('./img/%s' % image_name, 'wb') as f:              for chunk in r.iter_content(chunk_size=128):                  f.write(chunk)          print('Saved %s' % image_name)            # 使用Matlibplot展示图片          with open('./img/%s' % image_name, 'r') as f:              _img = mping.imread('./img/%s' % image_name)          if i==1:              plt.figure()          plt.subplot(2,3,i) # 2行三列显示在第i个位置          plt.imshow(_img)          plt.title(image_name)          plt.axis('off')          i=i+1  plt.show()