本篇开始,将会学习有关 Python 爬虫的相关知识,通过几篇的介绍,完整学习 Python 爬虫的方方面面。
在学习 Python 爬虫之前,我们首先需要下载安装 MongoDB,Redis 以及 MySQL。在学习爬虫的过程中都会使用到,之后的学习中默认已经完成相关软件的安装。
MongoDB Redis MySQL 相关问题
本人使用 Mac 开发,所以说一下 Mac 下相关软件的注意事项。
MongoDB
安装
使用
使用 mongo 命令进入交互模式:
exception in initAndListen: NonExistentPath: Data directory /data/db not found., terminating
因为未创建 /data/db 文件夹。我们可以使用:
转换链接的路径。
Redis
安装
我们通常会修改 /usr/local/etc/redis.conf 文件,注释 bind 127.0.0.1,解注释 requirepass,设置一个安全密码。
再使用:
brew service restart redis
|
重启 redis 服务。
使用
我们可以使用:
启动命令行程序。
在 redis 交互模式下再使用:
授权即可使用。
MySQL
安装
使用
启动:
brew services start mysql
|
进入交互模式:
Python 多版本共存问题
如果都配置到环境变量中,可以将其可执行文件取不同名来区别不同的 Python 和 pip。
爬虫
爬虫就是请求网站并提取数据的自动化程序。
urllib
urllib 是 Python 内置的 HTTP 请求库:
- urllib.request 请求模块
- urllib.error 异常处理模块
- urllib.parse url 解析模块
- urllib.robotparse robot.txt 解析模块
urllib.request 模块
urlopen 方法
urllib.request 最重要的方法就是 urlopen 方法:
urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=None, context=None)
|
import urllib.request
response = urllib.request.urlopen('http://www.baidu.com') print(response.read().decode('utf-8'))
|
import urllib.request import urllib.parse
data = bytes(urllib.parse.urlencode({'foo': 'bar'}), encoding='utf8') response = urllib.request.urlopen('http://httpbin.org/post', data=data) print(response.read().decode('utf-8'))
import json
data = bytes(json.dumps({'foo': 'bar'}), encoding='utf8') headers = { 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.108 Safari/537.36', 'Content-Type': 'application/json' } req = request.Request(url='http://httpbin.org/post', data=data, headers=headers) response = urllib.request.urlopen(req) print(response.read().decode('utf-8'))
|
import socket import urllib.request import urllib.error
response = urllib.request.urlopen('http://httpbin.org/get', timeout=1) print(response.read().decode('utf-8'))
try: response = urllib.request.urlopen('http://httpbin.org/get', timeout=0.1) except urllib.error.URLError as e: if isinstance(e.reason, socket.timeout): print('TIME OUT')
|
Request 方法
Request 方法用来处理 requestheader 等信息,构建的 request 对象可以直接传入 urlopen 方法:
from urllib import request from urllib import parse
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.108 Safari/537.36'} data = bytes(parse.urlencode({'foo': 'bar'}), encoding='utf8') url = 'http://httpbin.org/post'
req = request.Request(url=url, data=data, headers=headers)
response = request.urlopen(req) print(response.read().decode('utf-8'))
|
response 对象
import urllib.request response = urllib.request.urlopen('http://www.baidu.com') print(type(response))
print(response.status)
print(response.getheaders())
print(response.getheader('Server'))
|
ProxyHandler 方法
import urllib.request
proxy_handler = urllib.request.ProxyHandler(dict(http='http://112.85.129.159:9999', https='https://162.105.89.142:1080'))
opener = urllib.request.build_opener(proxy_handler) response = opener.open('http://httpbin.org/get') print(response.read().decode('utf-8'))
proxy_list = [ {"http" : "61.135.217.7:80"}, {"http" : "111.155.116.245:8123"}, {"http" : "122.114.31.177:808"}, ] proxy = random.choice(proxy_list) proxy_handler = urllib.request.ProxyHandler(proxy)
opener = urllib.request.build_opener(proxy_handler) response = opener.open('http://httpbin.org/get') print(response.read().decode('utf-8'))
|
HTTPCookieProcessor 方法
cookieJar = http.cookiejar.CookieJar() cookie_handler = urllib.request.HTTPCookieProcessor(cookieJar) opener = urllib.request.build_opener(cookie_handler) response = opener.open('http://www.baidu.com')
for cookie in cookieJar: print(cookie.name + '=' + cookie.value)
|
urllib.error 模块
from urllib import request, error
try: response = request.urlopen('https://github.com/1ess/404') except error.HTTPError as e: print(e.reason, e.code, e.headers, sep='\n') print(type(e.reason)) except error.URLError as e: print(e.reason) else: print('SUCCESS')
try: response = request.urlopen('https://github.com/1ess/404', timeout=0.01) except error.HTTPError as e: print(e.reason, e.code, e.headers, sep='\n') print(type(e.reason)) except error.URLError as e: print(e.reason) print(type(e.reason)) else: print('SUCCESS')
|
urllib.parse 模块
urlparse 方法
urllib.parse.urlparse(urlstring, scheme='', allow_fragments=True)
|
from urllib import parse
result = parse.urlparse('https://www.baidu.com/index.html?user=1ess#comment') print(type(result)) print(result)
result = parse.urlparse('www.baidu.com/index.html?user=1ess#comment', scheme='https') print(result)
result = parse.urlparse('http://www.baidu.com/index.html?user=1ess#comment', scheme='https') print(result)
result = parse.urlparse('http://www.baidu.com/index.html?user=1ess#comment', allow_fragments=False) print(result)
result = parse.urlparse('http://www.baidu.com/index.html#comment', allow_fragments=False) print(result)
|
urlunparse 方法
from urllib import parse
data = ['http', 'www.baidu.com', 'index.html', 'user', 'id=1', 'comment'] print(parse.urlunparse(data))
|
urljoin 方法
from urllib import parse
print(parse.urljoin('https://github.com', '/1ess'))
|
urlencode 方法
from urllib import parse
params = {'foo': 'bar'} base_url = 'http://www.baidu.com?' url = base_url + parse.urlencode(params) print(url)
|