Loading...

1.爬虫

网络爬虫就是模拟浏览器发送网络请求,接受请求响应,一种按照一定的规则,自动地抓取互联网信息的程序。

当我们在浏览器中输入一个url后按回车会发生什么:

  • 查找域名对应的IP地址
  • 向IP对应的服务器发送请求
  • 服务器响应请求吗,发回网页内容
  • 浏览器解析网页内容

经常使用到的库:

1
2
3
4
5
6
# -*- codeing = utf-8 -*-
from bs4 import BeautifulSoup #网页解析,获取数据
import re #正则表达式,进行文字匹配
import urllib.request, urllib.error #制定URL,获取网页数据
import xlwt #进行excel操作
import sqlite3 #进行SQLite数据库操

2.抓取

Python学习网络爬虫主要分3个大的版块:抓取,分析,存储;我们来详细说说抓取部分。

(1)基本抓取
抓取大多数都属于get请求,也就是说直接从对方服务器上获取数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Requests:
import requests
response = requests.get(url)
content = requests.get(url).content
print "response headers:", response.headers
print "content:", content
Urllib2:
import urllib2
response = urllib2.urlopen(url)
content = urllib2.urlopen(url).read()
print "response headers:", response.headers
print "content:", content
Httplib2:
import httplib2
http = httplib2.Http()
response_headers, content = http.request(url, 'GET')
print "response headers:", response_headers
print "content:", content

此外,对于带有查询字段的url,get请求一般会将来请求的数据附在url之后,以?分割url和传输数据,多个参数用&连接。

举个例子:

  • 基础URLhttp://www.example.com/products
  • 查询参数
    • category: “books”
    • sort: “price_asc”
1
http://www.example.com/products?category=books&sort=price_asc
1
2
3
4
5
6
7
8
9
data = {'data1':'XXXXX', 'data2':'XXXXX'}
Requests:data为dict,json
import requests
response = requests.get(url=url, params=data)
Urllib2:data为string
import urllib, urllib2
data = urllib.urlencode(data)
full_url = url+'?'+data
response = urllib2.urlopen(full_url)

(2)对登录情况的处理

  • 表单
  • cooike
1
2
3
4
5
6
7
8
9
data = {'data1':'XXXXX', 'data2':'XXXXX'}
Requests:data为dict,json
import requests
response = requests.post(url=url, data=data)
Urllib2:data为string
import urllib, urllib2
data = urllib.urlencode(data)
req = urllib2.Request(url=url, data=data)
response = urllib2.urlopen(req)
1
2
3
import requests			
requests_session = requests.session()
response = requests_session.post(url=url_login, data=data)

(3)反爬虫机制
限制IP地址情况,也可解决由于“频繁点击”而需要输入验证码登陆的情况。

这种情况最好的办法就是维护一个代理IP池,网上有很多免费的代理IP,良莠不齐,可以通过筛选找到能用的。对于“频繁点击”的情况,我们还可以通过限制爬虫访问网站的频率来避免被网站禁掉。

1
2
3
4
5
6
7
8
9
10
proxies = {'http':'http://XX.XX.XX.XX:XXXX'}
Requests:
import requests
response = requests.get(url=url, proxies=proxies)
Urllib2:
import urllib2
proxy_support = urllib2.ProxyHandler(proxies)
opener = urllib2.build_opener(proxy_support, urllib2.HTTPHandler)
urllib2.install_opener(opener) # 安装opener,此后调用urlopen()时都会使用安装过的opener对象
response = urllib2.urlopen(url)

有些网站会检查你是不是真的浏览器访问,还是机器自动访问的。这种情况,加上User-Agent,表明你是浏览器访问即可。有时还会检查是否带Referer信息还会检查你的Referer是否合法,一般再加上Referer。

1
2
3
4
5
6
7
8
9
headers = {'User-Agent':'XXXXX'} # 伪装成浏览器访问,适用于拒绝爬虫的网站
headers = {'Referer':'XXXXX'}
headers = {'User-Agent':'XXXXX', 'Referer':'XXXXX'}
Requests:
response = requests.get(url=url, headers=headers)
Urllib2:
import urllib, urllib2
req = urllib2.Request(url=url, headers=headers)
response = urllib2.urlopen(req)

3.实例分析

假设我们使用的网址是:https://movie.douban.com/top250

解释:豆瓣用户每天都在对“看过”的电影进行“很差”到“力荐”的评价,豆瓣根据每部影片看过的人数以及该影片所得的评价等综合数据,通过算法分析产生豆瓣电影 Top 250。

(1)爬取网页
爬取网页,这里的baseurl就是我们要爬虫的网页网址,调用了getData函数。

1
2
datalist = getData(baseurl)
savepath = "豆瓣电影Top250.xls" #当前目录新建XLS,存储进去

接下来我们来看一下getData函数:

1
2
3
4
5
6
7
8
9
10
11
# 爬取网页
def getData(baseurl):
datalist = [] #用来存储爬取的网页信息

for i in range(0, 10):
"""
调用获取页面信息的函数10次
因为电影评分Top250,每个页面只显示25个,所以我们需要访问页面10次,25*10=250。
"""
url = baseurl + str(i * 25)
html = askURL(url) # 保存获取到的网页源码

这里使用了askURL函数,我们来看看这个函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def askURL(url):
head = { # 模拟浏览器头部信息,向豆瓣服务器发送消息
"User-Agent": "Mozilla / 5.0(Windows NT 10.0; Win64; x64) AppleWebKit / 537.36(KHTML, like Gecko) Chrome / 80.0.3987.122 Safari / 537.36"
}
# 用户代理,表示告诉豆瓣服务器,我们是什么类型的机器、浏览器(本质上是告诉浏览器,我们可以接收什么水平的文件内容)

request = urllib.request.Request(url, headers=head)
html = ""
try:
response = urllib.request.urlopen(request)
html = response.read().decode("utf-8")
except urllib.error.URLError as e:
if hasattr(e, "code"):
print(e.code)
if hasattr(e, "reason"):
print(e.reason)
return html

接下来我们继续看getData函数剩下的内容:
(2)逐一解析数据
解析数据需要用到BeautifulSoup这个库,下面我们就开始查找符合我们要求的数据,用BeautifulSoupre库的正则表达式去匹配,匹配到符合要求的数据,然后存进datalist:

1
2
3
4
5
6
7
findLink = re.compile(r'<a href="(.*?)">')  # 创建正则表达式对象,标售规则   影片详情链接的规则
findImgSrc = re.compile(r'<img.*src="(.*?)"', re.S)
findTitle = re.compile(r'<span class="title">(.*)</span>')
findRating = re.compile(r'<span class="rating_num" property="v:average">(.*)</span>')
findJudge = re.compile(r'<span>(\d*)人评价</span>')
findInq = re.compile(r'<span class="inq">(.*)</span>')
findBd = re.compile(r'<p class="">(.*?)</p>', re.S)

最后我们来看最后有一步:
(3)保存数据

1
2
# 3.保存数据
saveData(datalist,savepath) #2种存储方式可以只选择一种

保存方式分类:

  • xls 表, 需要(xlwt库支持)
  • sqlite数据库, 需要(sqlite3库支持)