爱气象,爱气象家园! 

气象家园

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博登陆

只需一步, 快速开始

搜索
查看: 18400|回复: 8

[源代码] 一点爬虫的小应用:爬取PyNGL/PyNIO的Tutorial Example

[复制链接]

新浪微博达人勋

发表于 2017-8-2 12:02:36 | 显示全部楼层 |阅读模式

登录后查看更多精彩内容~

您需要 登录 才可以下载或查看,没有帐号?立即注册 新浪微博登陆

x
本帖最后由 8828 于 2017-8-13 18:16 编辑

最近想学学PyNGL和PyNIO, 但是没联网,于是学了一下爬虫,把官网Tutorial中的Example爬下来,留着没网的时候用。看了一下家园里爬虫的帖子,不是很多,可能前辈们都玩得很cool了吧,我就趁机发个帖子请前辈们批评指点,感谢! :)

#发帖的时候有的文字没了,吃完饭再补上吧 :- |
##################################
爬取内容:1.网页的讲解文字内容
     2.程序结果(.jpg)
     3.脚本(.py)
##################################
准备内容:1.Linux-Python 3.x
     2. requests   
     3. BeautifulSoup
     4. PIL
     5. BytesIO
     6. os
     7. time
###################################
  1. 爬取思路:这次是纯手动爬取,更高级的有scrapy, selenium...
复制代码
#########################
  1. def get_soup(url):
  2.     try:
  3.         response = requests.get(url)
  4.         response.encoding = response.apparent_encoding
  5.         text = response.text
  6.         print(response.status_code)
  7.         soup = BeautifulSoup(text, 'lxml')
  8.         return soup
  9.     except:
  10.          print("ERROR")
复制代码
做汤:
1.response = request.get(url, [headers]) 模拟浏览器发送请求, headers是一个字典,多数情况下是包含浏览器信息的,增加访问的成功率,可以利用      浏览器开发者工具的Network选项查询到
2. 编码
3. 获取html code,对应开发者工具中的Element 选项
4. 打印状态信息,200表示成功
5. 利用BeautifulSoup加工html code, 便于提取信息,需要安装lxml库。(也有其他选项)

#############################################
  1. def get_urls(url=tutorial_url):
  2.     soup = get_soup(url)
  3.     info = soup.find_all('tr')
  4.     contents = {}

  5.     for infos in info:
  6.         try:
  7.             intro = infos.get_text().strip().split('\n')
  8.             name = intro[0].replace(' ', '_')
  9.             link = tutorial_url + infos.a.attrs['href']
  10.             contents[name] = link

  11.             os.mkdir(path + '/' + name)
  12.             os.chdir(path + '/' + name)
  13.             with open(name + '.txt', 'a') as f:
  14.                   for word in intro:
  15.                        f.write(word)
  16.                        f.write('\n')
  17.          except:
  18.               print("URL ERROR")

  19.     return contents
复制代码
提取Examples 的url保存在contents字典中:
1. 通过右击inspect网页上感兴趣的元素在html code 的位置可以找到它info = soup.find_all('tr') 找到所有含有‘tr’的标签, 里面有想要的url信息。
2. intro = infos.get_text().strip().split('\n')  中 get_text()方法获得文本内容,包含了对Example的介绍
3. link = tutorial_url + infos.a.attrs['href'] 中 .a 表示tag <a href=' url '>, .attrs返回一个字典,['href']获得value
4. os.mkdir, os.chdir 用于创建不同Example的文件夹,以及进入对应文件夹保存文件#####################################################

  1. def get_img_urls(url):
  2.     soup = get_soup(url)
  3.     imgs = soup.find_all('td')
  4.     urls = []
  5.     for img in imgs:
  6.         try:
  7.             link = raw_url + img.a.attrs['href']
  8.             urls.append(link)
  9.         except:
  10.             print("IMG URL ERROR")

  11.      return urls
复制代码
获取Examples 中结果的url, 这是图片的url,用于爬取图片。思路同上。
#############################################
  1. def get_img_content(urls, dir_path):
  2.     for index, url in enumerate(urls):
  3.         try:
  4.             response = requests.get(url)
  5.             time.sleep(0.02)
  6.             img = Image.open(BytesIO(response.content))
  7.             file = dir_path + '/' + 'output_' + str(index) + '.png'
  8.             img.save(file)
  9.         except:
  10.             print("IMG STORE ERROR")
复制代码
保存图片内容:
1. response获取响应内容
2. time.sleep(0.02) 休息一下,防止ip被封
3. response.content 图片的字节流
4. BytesIO 存放字节流
5. PIL.Image.open() 打开字节流
6. save() 保存
#############################################
  1. def get_content(contents, path=path):
  2.     names = list(contents.keys())
  3.     urls = list(contents.values())
  4.     for name, url in zip(names, urls):
  5.         try:
  6.             soup = get_soup(url)
  7.             main = soup.find('div', class_='main')
  8.             text = main.get_text().strip().split('\n')
  9.             start = text.index('  0. #')
  10.             end = -3
  11.             img_urls = get_img_urls(url)

  12.             dir_path = path + '/' + name
  13.             os.chdir(dir_path)
  14.             with open(name + '.txt', 'a') as f:
  15.                 for word in text[start:end]:
  16.                     f.write(word)
  17.                     f.write('\n')

  18.             get_img_content(img_urls, dir_path)
  19.      except:
  20.             print("CONTENT ERROR")
复制代码
筛选所需信息并存储
1. main = soup.find('div', class_='main')  中.find 返回符合条件的第一项,相当于.find_all()中关键字limit=1, class_对应CSS,也可写成字典形式
2.  其余代码多用于处理字符串,显得很臃肿,编程刚算入门,写代码的水平有限,sorry
#############################################
  1. def get_script(path=path, script_url=script_url):
  2.     for i in range(101, 112):
  3.         try:
  4.             url = script_url.replace('  ', str(i)[1:])
  5.             try:
  6.                  if (str(i)[1:].index('0') == 0):
  7.                      name = 'Example_' + str(i)[-1]
  8.                  else:
  9.                      name = 'Example_' + str(i)[1:]
  10.              except:
  11.                    name = 'Example_' + str(i)[1:]
  12.              filename = path + '/' + name + '/' + name + '.py'
  13.              response = requests.get(url)
  14.              text = response.text.split('\n')
  15.              with open(filename, 'w') as f:
  16.                    for word in text:
  17.                         f.write(word)
  18.                         f.write('\n')
  19.         except:
  20.               print("SCRIPT ERROR")
复制代码
获取脚本内容:
1. 观察脚本的url可以发现,只是换了换数字来对应相关的Example,写个循环就可搞定
2. 原理与前面类似,只是多了一些字符串的技巧,我的字符串技巧太烂,勉强看看吧


#############################################
完整代码:
  1. # coding: utf-8
  2. import requests
  3. from bs4 import BeautifulSoup
  4. from PIL import Image
  5. from io import BytesIO
  6. import os
  7. import time

  8. raw_url = 'https://www.pyngl.ucar.edu'
  9. tutorial_url = 'https://www.pyngl.ucar.edu/Tutorial/'
  10. script_url = 'https://www.pyngl.ucar.edu/Examples/Scripts/ngl  p.py'
  11. path = '/media/wangweiyi/FILE/Documents/python/pyngl/example'


  12. def get_soup(url):
  13.     try:
  14.         response = requests.get(url)
  15.         response.encoding = response.apparent_encoding
  16.         text = response.text
  17.         print(response.status_code)
  18.         soup = BeautifulSoup(text, 'lxml')
  19.         return soup
  20.     except:
  21.         print("ERROR")


  22. def get_urls(url=tutorial_url):
  23.     soup = get_soup(url)
  24.     info = soup.find_all('tr')
  25.     contents = {}
  26.     for infos in info:
  27.         try:
  28.               intro = infos.get_text().strip().split('\n')
  29.               name = intro[0].replace(' ', '_')
  30.               link = tutorial_url + infos.a.attrs['href']
  31.               contents[name] = link
  32.               os.mkdir(path + '/' + name)
  33.               os.chdir(path + '/' + name)
  34.               with open(name + '.txt', 'a') as f:
  35.                      for word in intro:
  36.                            f.write(word)
  37.                            f.write('\n')
  38.          except:
  39.                  print("URL ERROR")

  40.     return contents


  41. def get_img_urls(url):
  42.      soup = get_soup(url)
  43.      imgs = soup.find_all('td')
  44.      urls = []
  45.      for img in imgs:
  46.           try:
  47.                 link = raw_url + img.a.attrs['href']
  48.                 urls.append(link)
  49.          except:
  50.                  print("IMG URL ERROR")

  51.         return urls


  52. def get_img_content(urls, dir_path):
  53.        for index, url in enumerate(urls):
  54.                try:
  55.                      response = requests.get(url)
  56.                      time.sleep(0.02)
  57.                      img = Image.open(BytesIO(response.content))
  58.                       file = dir_path + '/' + 'output_' + str(index) + '.png'
  59.                       img.save(file)
  60.                  except:
  61.                        print("IMG STORE ERROR")


  62. def get_content(contents, path=path):
  63.         names = list(contents.keys())
  64.         urls = list(contents.values())
  65.         for name, url in zip(names, urls):
  66.                try:
  67.                       soup = get_soup(url)
  68.                       main = soup.find('div', class_='main')
  69.                       text = main.get_text().strip().split('\n')
  70.                       start = text.index('  0. #')
  71.                       end = -3
  72.                       img_urls = get_img_urls(url)

  73.                       dir_path = path + '/' + name
  74.                       os.chdir(dir_path)
  75.                       with open(name + '.txt', 'a') as f:
  76.                                  for word in text[start:end]:
  77.                                  f.write(word)
  78.                                  f.write('\n')

  79.                         get_img_content(img_urls, dir_path)
  80.                    except:
  81.                           print("CONTENT ERROR")


  82. def get_script(path=path, script_url=script_url):
  83.         for i in range(101, 112):
  84.               try:
  85.                      url = script_url.replace('  ', str(i)[1:])
  86.                      try:
  87.                             if (str(i)[1:].index('0') == 0):
  88.                                    name = 'Example_' + str(i)[-1]
  89.                             else:
  90.                                    name = 'Example_' + str(i)[1:]
  91.                      except:
  92.                               name = 'Example_' + str(i)[1:]
  93.                     filename = path + '/' + name + '/' + name + '.py'
  94.                     response = requests.get(url)
  95.                     text = response.text.split('\n')
  96.                     with open(filename, 'w') as f:
  97.                              for word in text:
  98.                                      f.write(word)
  99.                                       f.write('\n')
  100.                     except:
  101.                             print("SCRIPT ERROR")


  102. def main(tutorial_url=tutorial_url, script_url=script_url, path=path):
  103.         contents = get_urls(tutorial_url)
  104.         get_content(contents)
  105.         get_script(path, script_url)


  106. if __name__ == '__main__':
  107.      main()
复制代码







Screenshot from 2017-08-02 12-07-36.png
Screenshot from 2017-08-02 12-08-18.png
Screenshot from 2017-08-02 12-10-35.png
Screenshot from 2017-08-02 14-07-32.png

pyngl.py

3.59 KB, 下载次数: 8, 下载积分: 金钱 -5

BeautifulSoup.pdf

416.22 KB, 下载次数: 10, 下载积分: 金钱 -5

评分

参与人数 1金钱 +15 贡献 +5 收起 理由
mofangbao + 15 + 5

查看全部评分

密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2017-8-2 12:10:06 | 显示全部楼层
{:eb502:}{:eb502:}
密码修改失败请联系微信:mofangbao
回复

使用道具 举报

新浪微博达人勋

发表于 2017-8-3 12:36:45 | 显示全部楼层
{:eb502:}{:eb502:}{:eb502:}{:eb502:}{:eb502:}
密码修改失败请联系微信:mofangbao
回复

使用道具 举报

新浪微博达人勋

发表于 2017-8-6 23:03:40 | 显示全部楼层
{:5_238:}
密码修改失败请联系微信:mofangbao
回复

使用道具 举报

新浪微博达人勋

发表于 2017-8-7 19:07:42 | 显示全部楼层
好东西,留着学习学习
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2017-8-7 19:40:51 | 显示全部楼层
{:5_213:}{:5_213:}{:5_213:}
密码修改失败请联系微信:mofangbao
回复

使用道具 举报

新浪微博达人勋

发表于 2017-8-8 14:18:08 | 显示全部楼层
收藏,学习python中
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2017-8-8 14:22:21 | 显示全部楼层
我要是大学时候有你这样的觉悟 就不至于现在画点图磨磨唧唧的了
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2020-1-4 16:02:27 | 显示全部楼层
收藏学习,谢谢楼主分享~
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册 新浪微博登陆

本版积分规则

Copyright ©2011-2014 bbs.06climate.com All Rights Reserved.  Powered by Discuz! (京ICP-10201084)

本站信息均由会员发表,不代表气象家园立场,禁止在本站发表与国家法律相抵触言论

快速回复 返回顶部 返回列表