VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > 编程开发 > python爬虫 >
  • python爬虫入门(一)urllib和urllib2

爬虫简介

 什么是爬虫?

爬虫:就是抓取网页数据的程序。

HTTP和HTTPS

HTTP协议(HyperText Transfer Protocol,超文本传输协议):是一种发布和接收 HTML页面的方法。

HTTPS(Hypertext Transfer Protocol over Secure Socket Layer)简单讲是HTTP的安全版,在HTTP下加入SSL层。

SSL(Secure Sockets Layer 安全套接层)主要用于Web的安全传输协议,在传输层对网络连接进行加密,保障在Internet上数据传输的安全。

浏览器发送HTTP请求的过程:

  1. 当用户在浏览器的地址栏中输入一个URL并按回车键之后,浏览器会向HTTP服务器发送HTTP请求。HTTP请求主要分为“Get”和“Post”两种方法。

  2. 当我们在浏览器输入URL http://www.baidu.com 的时候,浏览器发送一个Request请求去获取 http://www.baidu.com 的html文件,服务器把Response文件对象发送回给浏览器。

  3. 浏览器分析Response中的 HTML,发现其中引用了很多其他文件,比如Images文件,CSS文件,JS文件。 浏览器会自动再次发送Request去获取图片,CSS文件,或者JS文件。

  4. 当所有的文件都下载成功后,网页会根据HTML语法结构,完整的显示出来了。

URL(Uniform / Universal Resource Locator的缩写)

定义:统一资源定位符,是用于完整地描述Internet上网页和其他资源的地址的一种标识方法。

基本格式:scheme://host[:port#]/path/…/[?query-string][#anchor]

  • scheme:协议(例如:http, https, ftp)
  • host:服务器的IP地址或者域名
  • port#:服务器的端口(如果是走协议默认端口,缺省端口80)
  • path:访问资源的路径
  • query-string:参数,发送给http服务器的数据
  • anchor:锚(跳转到网页的指定锚点位置)

客户端HTTP请求

URL只是标识资源的位置,而HTTP是用来提交和获取资源。客户端发送一个HTTP请求到服务器的请求消息,包括以下格式:

请求行请求头部空行请求数据

一个典型的HTTP请求

复制代码
GET https://www.baidu.com/ HTTP/1.1
Host: www.baidu.com
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: zh,zh-CN;q=0.8,ar;q=0.6,zh-TW;q=0.4
Cookie: BAIDUID=AE4D1DA6B2D6689BB8C557B3436893E3:FG=1; BIDUPSID=AE4D1DA6B2D6689BB8C557B3436893E3; PSTM=1501466227; BD_UPN=12314353; BD_CK_SAM=1; PSINO=1; H_PS_PSSID=1420_25548_21080_20929; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; BDSVRTM=0
复制代码
 常用请求报头
 cookie和session

HTTP请求方法

复制代码
序号   方法      描述
1     GET       请求指定的页面信息,并返回实体主体。
2     HEAD      类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头
3     POST      向指定资源提交数据进行处理请求(例如提交表单或者上传文件),数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。
4     PUT       从客户端向服务器传送的数据取代指定的文档的内容。
5     DELETE    请求服务器删除指定的页面。
6     CONNECT   HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。
7     OPTIONS   允许客户端查看服务器的性能。
8     TRACE     回显服务器收到的请求,主要用于测试或诊断。
复制代码

主要方法get和post请求

  • GET是从服务器上获取数据,POST是向服务器传送数据

  • GET请求参数显示,都显示在浏览器网址上,HTTP服务器根据该请求所包含URL中的参数来产生响应内容,即“Get”请求的参数是URL的一部分。 例如: http://www.baidu.com/s?wd=Chinese

  • POST请求参数在请求体当中,消息长度没有限制而且以隐式的方式进行发送,通常用来向HTTP服务器提交量比较大的数据(比如请求中包含许多参数或者文件上传操作等),请求的参数包含在“Content-Type”消息头里,指明该消息体的媒体类型和编码.

HTTP响应状态码

 View Code

浏览器内核

复制代码
浏览器                         内核
IE                           Trident
Chrome                       Webkit
Firefox                      Gecho
Opera                        Pesto
Safari(Apple)                Webkit 
复制代码

HTTP代理工具Fiddler
Fiddler是一款强大Web调试工具,它能记录所有客户端和服务器的HTTP请求.

Request部分详解

  1. Headers —— 显示客户端发送到服务器的 HTTP 请求的 header,显示为一个分级视图,包含了 Web 客户端信息、Cookie、传输状态等。
  2. Textview —— 显示 POST 请求的 body 部分为文本。
  3. WebForms —— 显示请求的 GET 参数 和 POST body 内容。
  4. HexView —— 用十六进制数据显示请求。
  5. Auth —— 显示响应 header 中的 Proxy-Authorization(代理身份验证) 和 Authorization(授权) 信息.
  6. Raw —— 将整个请求显示为纯文本。
  7. JSON - 显示JSON格式文件。
  8. XML —— 如果请求的 body 是 XML 格式,就是用分级的 XML 树来显示它。

 Responser部分详解

  1. Transformer —— 显示响应的编码信息。
  2. Headers —— 用分级视图显示响应的 header。
  3. TextView —— 使用文本显示相应的 body。
  4. ImageVies —— 如果请求是图片资源,显示响应的图片。
  5. HexView —— 用十六进制数据显示响应。
  6. WebView —— 响应在 Web 浏览器中的预览效果。
  7. Auth —— 显示响应 header 中的 Proxy-Authorization(代理身份验证) 和 Authorization(授权) 信息。
  8. Caching —— 显示此请求的缓存信息。
  9. Privacy —— 显示此请求的私密 (P3P) 信息。
  10. Raw —— 将整个响应显示为纯文本。
  11. JSON - 显示JSON格式文件。
  12. XML —— 如果响应的 body 是 XML 格式,就是用分级的 XML 树来显示它 。

 了解了这些知识后,接下来真正迈向爬虫之路.......

urllib2

所谓网页抓取,就是把URL地址中指定的网络资源从网络流中读取出来,保存到本地。 在Python中有很多库可以用来抓取网页,先学习urllib2

urllib2模块直接导入就可以用,在python3中urllib2被改为urllib.request

开始爬虫需要准备的一些工具

(1)下载Fiddeler抓包工具,百度直接下载安装就可以(抓包)

(2)下载chrome浏览器代理插件 Proxy-SwitchyOmega(代理)

(3)下载chrome浏览器插件XPath(解析HTML)

(4)工具网站:

      http://www.json.cn/     (json解析网站)

      http://tool.chinaz.com/tools/urlencode.aspx     (url编码解码网站)

先写个简单的爬虫百度页面

urlopen

复制代码
# _*_ coding:utf-8 _*_
import urllib2

#向指定的url地址发送请求,并返回服务器响应的类文件对象
response = urllib2.urlopen('http://www.baidu.com/')
#服务器返回的类文件对象支持python文件对象的操作方法
#read()方法就是读取文件里的全部内容,返回字符串
html = response.read()
print html
复制代码

urllib2默认的User-Agent是Python-urllib/2.7,容易被检查到是爬虫,所以我们要构造一个请求对象,要用到request方法。

模拟浏览器访问

浏览器访问时通过抓包工具获得的headers信息如下:

复制代码
GET https://www.baidu.com/ HTTP/1.1
Host: www.baidu.com
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: zh,zh-CN;q=0.8,ar;q=0.6,zh-TW;q=0.4
Cookie: BAIDUID=AE4D1DA6B2D6689BB8C557B3436893E3:FG=1; BIDUPSID=AE4D1DA6B2D6689BB8C557B3436893E3; PSTM=1501466227; BD_CK_SAM=1; PSINO=1; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; BD_HOME=0; H_PS_PSSID=1420_25548_21080_20929; BD_UPN=12314353
复制代码

我们要设置User-Agent模仿浏览器去访问数据

复制代码
# _*_ coding:utf-8 _*_
import urllib2

# User-Agent是爬虫与反爬虫的第一步
ua_headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari/537.36'}
# 通过urllib2.Request()方法构造一个请求对象
request = urllib2.Request('http://www.baidu.com/',headers=ua_headers)

#向指定的url地址发送请求,并返回服务器响应的类文件对象
response = urllib2.urlopen(request)

# 服务器返回的类文件对象支持python文件对象的操作方法
# read()方法就是读取文件里的全部内容,返回字符串
html = response.read()

print html
复制代码

Request总共三个参数,除了必须要有url参数,还有下面两个:

  1. data(默认空):是伴随 url 提交的数据(比如要post的数据),同时 HTTP 请求将从 "GET"方式 改为 "POST"方式。

  2. headers(默认空):是一个字典,包含了需要发送的HTTP报头的键值对。

response的常用方法

复制代码
# _*_ coding:utf-8 _*_
import urllib2

# User-Agent是爬虫与反爬虫的第一步
ua_headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari/537.36'}
# 通过urllib2.Request()方法构造一个请求对象
request = urllib2.Request('http://www.baidu.com/',headers=ua_headers)

#向指定的url地址发送请求,并返回服务器响应的类文件对象
response = urllib2.urlopen(request)

# 服务器返回的类文件对象支持python文件对象的操作方法
# read()方法就是读取文件里的全部内容,返回字符串
html = response.read()

# 返回HTTP的响应吗,成功返回200,4服务器页面出错,5服务器问题
print response.getcode()     #200

# 返回数据的实际url,防止重定向
print response.geturl()     #https://www.baidu.com/

# 返回服务器响应的HTTP报头
print response.info()

# print html
复制代码

随机选择一个Use-Agent

为了防止封IP,先生成一个user-agent列表,然后从中随机选择一个

复制代码
# _*_ coding:utf-8 _*_
import urllib2
import random

url = 'http:/www.baidu.com/'

# 可以试User-Agent列表,也可以是代理列表
ua_list = ["Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1",
    "Mozilla/5.0 (X11; CrOS i686 2268.111.0) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11",
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1092.0 Safari/536.6",
    "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1090.0 Safari/536.6",
    "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/19.77.34.5 Safari/537.1",
    "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.9 Safari/536.5",
    "Mozilla/5.0 (Windows NT 6.0) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.36 Safari/536.5",
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
    "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_0) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
    "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3",
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3",
    "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
    "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
    "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.0 Safari/536.3",
    "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24",
    "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24"
]

# 在User-Agent列表中随机选择一个User-Agent
user_agent = random.choice(ua_list)

# 构造一个请求
request = urllib2.Request(url)

# add_header()方法添加/修改一个HTTP报头
request.add_header('User-Agent',user_agent)

#get_header()获取一个已有的HTTP报头的值,注意只能第一个字母大写,后面的要小写
print request.get_header('User-agent')
复制代码

urllib和urllib2的主要区别

 urllib和urllib2都是接受URL请求的相关模块,但是提供了不同的功能,最显著的区别如下:

(1)urllib仅可以接受URL,不能创建,设置headers的request类实例;

(2)但是urllib提供urlencode()方法用来GET查询字符串的产生,而urllib2则没有(这是urllib和urllib2经常一起使用的主要原因)

(3)编码工作使用urllib的urlencode()函数,帮我们讲key:value这样的键值对转换成‘key=value’这样的字符串,解码工作可以使用urllib的unquote()

函数

 urllib.encode()的使用

urlencode()里面必须是字典类型

复制代码
# _*_ coding:utf-8 _*_
import urllib

dic = {'derek':'编码'}
print urllib.urlencode(dic)    #derek=%E7%BC%96%E7%A0%81

m = urllib.urlencode(dic)

print urllib.unquote(m)         #derek=编码
复制代码
一般HTTP请求提交数据,需要编码成 URL编码格式,然后做为url的一部分,或者作为参数传到Request对象中。

GET请求一般用于我们向服务器获取数据,比如说,我们用百度搜索知乎:https://www.baidu.com/s?wd=知乎

发现GEThttps://www.baidu.com/s?wd=%E7%9F%A5%E4%B9%8E,后面是一个长长的字符串,urldecode后发现就是知乎

 

 

用urllib.urlencode()进行转码,然后组合url

复制代码
# _*_ coding:utf-8 _*_
import urllib,urllib2

url = 'http://www.baidu.com/s'
headers = {'UserAgent':'Mozilla'}
keyword = raw_input('请输入关键字:')
wd = urllib.urlencode({'wd':keyword})
fullurl = url + '?' + wd
print fullurl
request = urllib2.Request(fullurl,headers=headers)
response = urllib2.urlopen(request)
print response.read()
复制代码

然后输入关键字,爬取下对应的内容

 

爬取贴吧内容

 先了解贴吧url组成:

每个贴吧url都是以'https://tieba.baidu.com/f?'开头,然后是关键字 kw=‘’贴吧名字‘’,再后面是 &pn=页数  (pn=0第一页,pn=50第二页,依次类推)

1.先写一个main,提示用户输入要爬取的贴吧名,并用urllib.urlencode()进行转码,然后组合url

2.接下来,写一个百度贴吧爬虫接口tiebaSpider(),需要传递3个参数给这个接口, 一个是main里组合的url地址,以及起始页码和终止页码,表示要爬取页码的范围。

3.前面写出一个爬取一个网页的代码。然后,将它封装成一个小函数loadPage(),供我们使用。

4.将爬取到的每页的信息存储在本地磁盘上,我们可以简单写一个存储文件的接口writePage()

复制代码
# _*_ coding:utf-8 _*_
import urllib,urllib2

def loadPage(url,filename):
    #根据url发送请求,获取服务器响应文件
    print '正在下载' + filename
    headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari/537.36'}
    request = urllib2.Request(url,headers = headers)
    content = urllib2.urlopen(request).read()
    return content
def writePage(html,filename):
    #将html内容写入到本地
    print '正在保存' + filename
    with open(unicode(filename,'utf-8'),'w') as f:
        f.write(html)
    print '_' * 30

def tiebaSpider(url,beginPage,endPage):
    #贴吧爬虫调度器,负责组合处理每个页面的url
    for page in range(beginPage,endPage + 1):
        pn = (page - 1) * 50
        filename = '' + str(page) + '页.html'
        fullurl = url + '&pn=' + str(pn)
        # print fullurl
        html = loadPage(fullurl,filename)
        writePage(html,filename)

if __name__ == '__main__':
    kw = raw_input('请输入贴吧名:')
    beginPage = int(raw_input('请输入起始页:'))
    endPage = int(raw_input('请输入结束页:'))

    url = 'https://tieba.baidu.com/f?'
    key = urllib.urlencode({'kw':kw})
    fullurl = url + key
    tiebaSpider(fullurl,beginPage,endPage)
复制代码

通过输入想要搜索的贴吧名字,爬取内容并保存到本地

 获取Ajax方式加载的数据

爬虫最需要关注的不是页面信息,而是页面信息的数据来源

Ajax方式加载的页面,数据来源一定是JSON,直接对AJAX地址进行post或get,拿到JSON,就是拿到了网页数据,

(1)先通过浏览器访问豆瓣电影排行榜

https://movie.douban.com/typerank?type_name=%E5%89%A7%E6%83%85&type=11&interval_id=100:90&action=

 

(2)浏览器访问后,通过抓包工具就可以获取我们想要的一些信息

 

只要response里面有 JSON数据,我们就可以找到服务器的数据来源

分析发现变动的是start value和limit value, type,interval_id,action,固定不变,这三个url中已经包含了,所以formdata只用传start和limit

复制代码
import urllib
import urllib2


url = 'https://movie.douban.com/typerank?type_name=%E5%89%A7%E6%83%85&type=11&interval_id=100:90&action='
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari/537.36'}

# start和limit可以自己随便设置
formdata = {'start':'20','limit':'100'}

data = urllib.urlencode(formdata)
request = urllib2.Request(url,data = data,headers=headers)

response = urllib2.urlopen(request)
print response.read()
复制代码


 

出处:https://www.cnblogs.com/derek1184405959/p/8448875.html

相关教程