5.6. 简单的爬虫

爬虫(spider,又网络爬虫),是指向网站/网络发起请求,获取资源后分析并提取有用数据的程序。

从技术层面来说就是 通过程序模拟浏览器请求站点的行为, 把站点返回的HTML代码/JSON数据/二进制数据(图片、视频) 爬到本地, 进而提取自己需要的数据,存放起来使用。

5.6.1. 爬虫基本流程

用户获取网络数据的方式:

  1. 方式1:浏览器提交请求—>下载网页代码—>解析成页面

  2. 方式2:模拟浏览器发送请求(获取网页代码)->提取有用的数据->存放于数据库或文件中

爬虫要做的就是方式2。

  1. 发起请求

使用http库向目标站点发起请求,即发送一个Request

Request包含:请求头、请求体等

Request模块缺陷:不能执行JS 和CSS 代码

  1. 获取响应内容

如果服务器能正常响应,则会得到一个Response

Response包含:html,json,图片,视频等

  1. 解析内容

解析html数据:正则表达式(RE模块)、xpath(主要使用)、beautiful soup、css

解析json数据:json模块

解析二进制数据:以wb的方式写入文件

  1. 保存数据

数据库(MySQL,Mongdb、Redis)或 文件的形式。

5.6.2. 方法实例

爬取http://www.gissky.net GIS空间站相关信息

>>> import requests
>>> from bs4 import BeautifulSoup
>>> r  = requests.get("http://www.gissky.net/Category_25/Index_1.aspx")
>>> url = "http://www.gissky.net/Category_25/Index_1.aspx"
>>> # html = requests.urlopen(url,timeout= 60).read().decode('utf-8', 'ignore')
>>> soup = BeautifulSoup(r.text, 'html.parser')

解析相关信息的url规则

>>> pattern2 = '\/[A-Za-z]{4}\/[0-9]*\.aspx$'
>>> page = soup.find('div', {'class': 'home-left-list'})

查找当前页面的所有a标签,并进行进一步解析处理

>>> import re
>>> links = page.findAll('a')
>>> for link in links:
>>>     if re.match(pattern2, link['href']):
>>>         #如果url符合解析要求,则对该页面进行信息提取
>>>         url=link['href']
>>>         # 获取页面所有元素
>>>         out_url ='http://www.gissky.net'+url
>>>         print(out_url)
>>>
>>>         # html = requests.urlopen(out_url).read().decode('utf-8', 'ignore')
>>>         # soup = BeautifulSoup(html, 'html.parser')
>>>         # # 获取信息
>>>         # if not (soup.find('div', {'class': 'main_left'})):
>>>         #     continue
>>>         # page = soup.find('div', {'class': 'zwnr'})
>>>         # content = page.text
>>>         # size = soup.find('ul',{'class':'ruanjian'}).find_all('li')[1].text
>>>         # downloads = soup.find('div', {'class': 'intro_url'}).dl.a['href']
>>>         # downurl = 'http://www.gissky.net' + downloads.strip()
>>>         # title = soup.find('ul', {'class': 'ruanjian'}).li.span.text.replace(' ','')
>>>         # if '/' in title:
>>>         #     titles = title.replace('/', '')
>>>         # else:
>>>         #     titles = title
>>>         # print(size)
>>>         # print(downurl)
>>>         # print(titles)
http://www.gissky.net/Item/14787.aspx
http://www.gissky.net/Item/14787.aspx
http://www.gissky.net/Item/14786.aspx
http://www.gissky.net/Item/14786.aspx
http://www.gissky.net/Item/10075.aspx
http://www.gissky.net/Item/10075.aspx
http://www.gissky.net/Item/8466.aspx
http://www.gissky.net/Item/8466.aspx
http://www.gissky.net/Item/8465.aspx
http://www.gissky.net/Item/8465.aspx
http://www.gissky.net/Item/8464.aspx
http://www.gissky.net/Item/8464.aspx
http://www.gissky.net/Item/8463.aspx
http://www.gissky.net/Item/8463.aspx
http://www.gissky.net/Item/8462.aspx
http://www.gissky.net/Item/8462.aspx
http://www.gissky.net/Item/8461.aspx
http://www.gissky.net/Item/8461.aspx
http://www.gissky.net/Item/8460.aspx
http://www.gissky.net/Item/8460.aspx