1 何为爬虫

网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。另外一些不常使用的名字还有蚂蚁、自动索引、模拟程序或者蠕虫。摘自百度百科

2 URL

2.1 URL含义

URL(Uniform/Universal Resource Locator的缩写,统一资源定位符)是对可以从互联网上得到的资源的位置和访问方法的一种简洁的表示,是互联网上标准资源的地址。互联网上的每个文件都有一个唯一的URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它。它最初是由蒂姆·伯纳斯·李发明用来作为万维网的地址的。现在它已经被万维网联盟编制为因特网标准RFC1738了。

2.2 URL格式

一个完整的URL包括访问协议类型、主机地址、路径和文件名。

  • 访问协议类型:表示采用什么协议访问哪类资源,以便浏览器决定用什么方法获得资源
  • 主机地址:表示要访问的主机的IP地址或域名地址(包括端口)
  • 路径和文件名:表示信息在主机中的路径和文件名,如果缺省文件路径,则表示定位于Web服务器的主页,其文件名通常是index.htm。

3 浏览器网页过程

  • 输入地址
  • 浏览器查找域名的 IP 地址
  • 这一步包括 DNS 具体的查找过程,包括:浏览器缓存->系统缓存->路由器缓存...
  • 浏览器向 web 服务器发送一个 HTTP 请求
  • 服务器处理请求
  • 服务器返回一个 HTTP 响应
  • 浏览器显示 HTML
  • 浏览器发送请求获取嵌入在 HTML 中的资源(如图片、音频、视频、CSS、JS等等)
    用户看到的实际就是HTML,爬虫爬来的便是这些内容,通过分析和过滤这些 HTML 代码,来获取自己需要的资源,包括图片、文字等。

4 urllib—URL处理模块

4.1 如何使用urllib包来获取Internet资源

例:

>>> import urllib.request   ①
>>> with urllib.request.urlopen('https://www.baidu.com') as f:  ②
...     print(f.read())
...
b'<html>\r\n<head>\r\n\t<script>\r\n\t\tlocation.replace(location.href.replace("https://","http://"));\r\n\t</script>\r\n</head>\r\n<body>\r\n\t<noscript><meta http-equiv="refresh" content="0;url=http://www.baidu.com/"></n  ③

① 导入模块
② 用with语句来打开URL,urlopen一般常用的有三个参数,它的参数如下:urllib.requeset.urlopen(url,data,timeout),用f.read()方法来一次性读取全部内容,可以加参数来确定读取的字节数,如f.read(300)
③ 可以看到urlopen返回的是字节对象,如果确定html编码格式,可以使用decode来解码,如:f.read().decode('utf-8')

4.2 urlretrieve()

如果您希望通过URL检索资源并将其存储在一个临时位置,您可以通过urlretrieve()函数来实现这一功能,

import urllib.request
local_filename, headers = urllib.request.urlretrieve('http://python.org/')
html = open(local_filename)

5 POST和GET数据传送

5.1 通过GET方式发送

如果要想模拟浏览器发送GET请求,就需要使用Request对象,通过往Request对象add_header方法添加HTTP头,我们就可以把请求伪装成浏览器,上面的代码可以修改为下面这样:

import urllib.request

req = urllib.request.Request(url='https://www.baidu.com') ①
req.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.96 Safari/537.36') ②
with urllib.request.urlopen(req) as f:
    print(f.status)
    for k, v in f.getheaders(): ③ 
        print(k, v)

① 通过Request对象添加headers方式请求
②.add_header()方法添加头信息
③ 打印头信息

5.2 通过POST方式发送请求

只需要把参数data以bytes形式传入,下面代码是模拟的数据,做个例子使用:

from urllib import request, parse ①

login_data = bytes(parse.urlencode({'form_email': 'demo', 'form_password': '123456'}), encoding='utf-8')
print(login_data) ②

req = request.Request('http://httpbin.org/post') ③
req.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0')

response = request.urlopen(req, login_data)
print(response.read())

①导入request的parse模块
②这里就用到urllib.parse,通过bytes(urllib.parse.urlencode())可以将post数据进行转换放到urllib.request.urlopen的data参数中。这样就完成了一次post请求。如果我们添加data参数的时候就是以post请求方式请求,如果没有data参数就是get请求方式
③这个网址不错,可以作为练习urllib的各种方式(此处借鉴了scrounger的个人博客
今天就到这里,明天继续urllib的高级用法。