上节讲了理论,这节我们练习一下。

我们写个简单的看看,方面理解。

#!/usr/bin/python
#-*-coding:utf-8-*-
##
# @file 爬虫.py
# @brief 
# @author SongQiang
# @version 1.0
# @date 2019-01-10

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

 分析报头:

GET http://www.baidu.com/ HTTP/1.1
Accept-Encoding: identity
Host: www.baidu.com
Connection: close
User-Agent: Python-urllib/2.7

       直接用urllib2(User-Agent: Python-urllib/2.7)给一个网站发送请求的话,确实略有些唐突了,就好比,人家每家都有门,你以一个路人的身份直接闯进去显然不是很礼貌。而且有一些站点不喜欢被程序(非人为访问)访问,有可能会拒绝你的访问请求。

       浏览器 就是互联网世界上公认被允许的身份,如果我们希望我们的爬虫程序更像一个真实用户,那我们第一步,就是需要伪装成一个被公认的浏览器。用不同的浏览器在发送请求的时候,会有不同的User-Agent头。 urllib2默认的User-Agent头为:Python-urllib/x.y(x和y是Python主版本和次版本号,例如 Python-urllib/2.7)。

Get方式获取服务器数据 (爬取贴吧页面数据)

#!/usr/bin/python
# -*-coding:utf-8-*-
##
# @file 贴吧Spider.py
# @brief 
# @author SongQiang
# @version 1.0
# @date 2019-01-12

import urllib      #负责url编码处理
import urllib2

def tiebaSpider(url,beginPage,endPage):

    """
        作用:负责处理url,分配每个url去发送请求
        url:需要处理的第一个url
        beginPage: 爬虫执行的起始页面
        endPage: 爬虫执行的截止页面
    """
    for page in range(beginPage,endPage+1):
        pn=(page-1)*50

        filename="第"+str(page)+"页.html"
        #组合为完整的url 并且pn直每次增加50

        fullurl=url+"&pn="+str(pn)

        #调用loadPage()发送获取HTML页面
        html=loadPage(fullurl,filename)

        writeFile(html,filename)
def loadPage(url, filename):

    '''
    作用:根据url发送请求,获取服务器响应文件
    url:需要爬取的url地址
    filename: 文件名
    '''
    print "正在下载" + filename
    headers = {"User-Agent": "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0;"}
    request = urllib2.Request(url, headers = headers)
    response = urllib2.urlopen(request)
    return response.read()

def writeFile(html,filename):

    print "正在存储"+filename
    with open(filename,'w') as f:
        f.write(html)
    print "-"*20
#模拟main函数
if __name__=="__main__":
   
    kw=raw_input('请输入需要爬取的贴吧:')
    #输入起始页和终止页 str转为int类型
    beginPage=int(raw_input("请输入起始页"))
    endPage=int(raw_input("请输入终止页"))

    url = "http://tieba.baidu.com/f?"
    key = urllib.urlencode({"kw" : kw})
    
    #组合后url示例 http://tieba.baidu.com/f?kw=lol
    url=url+key
    tiebaSpider(url,beginPage,endPage)

  实例2中用了urllib,它跟urllib2不太一样,两个最显著的不同如下:

  • urllib 仅可以接受URL,不能创建 设置了headers 的Request 类实例;

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

  • 编码工作使用urllib的urlencode()函数,帮我们将key:value这样的键值对转换成"key=value"这样的字符串,解码工作可以使用urllib的unquote()函数。(注意,不是urllib2.urlencode() )

Post请求:

在看《精通Python网络爬虫》这本书中,韦老师提供了一个测试网址http://www.iqianyue.com/mypost

#!/usr/bin/env python
#-*- coding:utf8 -*-

##
# @file post请求
# @brief 
# @author SongQiang
# @version 1.0
# @date 2019-01-12

import urllib
import urllib2

#通过抓包的方式获取url 并不是浏览器的url
url="http://www.iqianyue.com/mypost"

#完整的headers
headers={
        "Accept" : "text/html, application/xhtml+xml",
        "Accept-Language" : "zh-CN",
        "User-Agent" : "Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko",
        }
# 发送到web服务器的表单数据
formdata = {
        "name" : "宋祁",
        "pass" : "123456",
        "" : "submit",
        }
# 经过urlencode转码
data = urllib.urlencode(formdata)

# 如果Request()方法里的data参数有值,那么这个请求就是POST
# 如果没有,就是Get
request = urllib2.Request(url, data = data, headers = headers)
html=urllib2.urlopen(request).read()
print "正在保存"
with open("post.html","w") as f:
    f.write(html)
print "-"*20

 获取AJAX加载的内容

 有些网页内容使用AJAX加载,只要记得,AJAX一般返回的是JSON,直接对AJAX地址进行post或get,就返回JSON数据了。

#!/usr/bin/env python
#-*- coding:utf8 -*-

##
# @file urllib_ajax.py
# @brief 
# @author SongQiang
# @version 1.0
# @date 2019-01-13

import urllib
import urllib2
url="https://movie.douban.com/j/search_subjects?type=movie&tag=%E5%8F%AF%E6%92%AD%E6%94%BE&sort=time"

headers={"User-Agent": "Mozilla...."}

# 变动的是这两个参数,从start开始往后显示limit个
formdata = {
    "page_limit":'60',
    "page_start":'0'
                }
data = urllib.urlencode(formdata)
request = urllib2.Request(url, data = data, headers = headers)
response = urllib2.urlopen(request)
print response.read()

 

 

 

 

 

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐