1. Python网络爬虫——V 1.0
Step 1 : 实现抓取Startup News,并运行
import re
import urllib.request
import urllib
from collections import deque
# 定义队列和集合
queue = deque()
visited = set()
url = 'http://news.dbanotes.net' # 入口页面, 可以换成别的
queue.append(url)
cnt = 0
while queue:
url = queue.popleft() # 队首元素出队
visited |= {url} # 标记为已访问
print('已经抓取: ' + str(cnt) + ' 正在抓取 <--- ' + url)
cnt += 1
urlop = urllib.request.urlopen(url)
# 由于正则表达式中设置,所有连接都会爬,但是假如是jpg、ico等文件,在转化为UTF-8过程中会出错
# 所以此处先判断其是文件类型,需要是HTML才继续进行分析
if 'html' not in urlop.getheader('Content-Type'):
continue
# 避免程序异常中止, 用try..catch处理异常
try:
data = urlop.read().decode('utf-8')
except:
continue
# 正则表达式提取页面中所有队列, 并判断是否已经访问过, 然后加入待爬队列
linkre = re.compile('href=\"(.+?)\"')
for x in linkre.findall(data):
if 'http' in x and x not in visited:
queue.append(x)
print('加入队列 ---> ' + x)
在调试期间,出现了如下异常:(明显是因为网站限制爬取页面导致的,暂时先不理这个异常)
urllib.error.HTTPError: HTTP Error 403: Forbidden
2. Python网络爬虫:V 2.0(伪装浏览器君)
Step 1 : 添加超时跳过功能
urlop = urllib.request.urlopen(url, timeout = 2)
Step 2 : 支持自动跳转
- 在某些URL被访问时,网站返回一个应该跳转的URL(比如 http://baidu.com 返回 应该跳转到 http://www.baidu.com )
- 首先,我们要知道爬 http://baidu.com 的时候返回的页面是怎么样的,其中页面内容如下:
<html>
<meta http-equiv=”refresh” content=”0;url=http://www.baidu.com/”>
</html>
- 看代码可知,这是一个利用 html 的 meta 来刷新与重定向的代码, 其中的0是等待0秒后跳转, 也就是立即跳转. 这样我们再像上一次说的那样用一个正则表达式把这个url提取出来就可以爬到正确的地方去了.
Step 3 : 伪装浏览器正规军
根据理论知识(HTTP报文)可知,在 GET 时,将 User-Agent 添加到header里
方法1:简便直接,但不好拓展功能
import urllib.request
url = 'http://www.baidu.com/'
req = urllib.request.Request(url, headers = {
'Connection': 'Keep-Alive',
'Accept': 'text/html, application/xhtml+xml, */*',
'Accept-Language': 'en-US,en;q=0.8,zh-Hans-CN;q=0.5,zh-Hans;q=0.3',
'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko'
})
oper = urllib.request.urlopen(req)
data = oper.read()
print(data.decode())
方法2:使用build_opener
这个方法, 用来自定义opener
,这种方法的好处是可以方便的拓展功能
import urllib.request
import http.cookiejar
# head: dict of header
def makeMyOpener(head = {
'Connection': 'Keep-Alive',
'Accept': 'text/html, application/xhtml+xml, */*',
'Accept-Language': 'en-US,en;q=0.8,zh-Hans-CN;q=0.5,zh-Hans;q=0.3',
'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko'
}):
cj = http.cookiejar.CookieJar()
opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj))
header = []
for key, value in head.items():
elem = (key, value)
header.append(elem)
opener.addheaders = header
return opener
oper = makeMyOpener()
uop = oper.open('http://www.baidu.com/', timeout = 1000)
data = uop.read()
print(data.decode())
Step 4 : 保存抓回来的报文
使用Python进行文件操作
def saveFile(data):
save_path = 'D:\\temp.out'
f_obj = open(save_path, 'wb') # wb 表示打开方式
f_obj.write(data)
f_obj.close()
# 这里省略爬虫代码
# ...
# 爬到的数据放到 dat 变量里
# 将 dat 变量保存到 D 盘下
saveFile(dat)
3. 开发网络爬虫: V 3.0 (登录)
Step 1 : 实现解压缩
import gzip
def ungzip(data):
try: # 尝试解压
print('正在解压.....')
data = gzip.decompress(data)
print('解压完毕!')
except:
print('未经压缩, 无需解压')
return data