简单python爬虫

初学python,借鉴网上一些资料尝试了一个简单的爬虫小程序,这是非常简单的爬网页图片的代码。

一,版本问题

开始在网上找到的简易爬虫小程序是下面这个:

简易爬虫小程序

讲解的很是详细,但是这个好像并不是用Python3.x写的,代码并不能直接用,在Python3 之后很多包都有所改动,像这篇博客代码中的urllib,re就有改动,改完之后与java的正则匹配倒是有些相似。通过查找api和搜索引擎将版本问题解决了。

二,非法访问(Bad Request)

启动程序,就遇到了一些问题,总是报出“400 Bad Request”的错误,这是非法访问的意思,我在网上查到可能是由于非人访问时,Python发过去的头并不是浏览器访问的头部,而是以,需要为其添加头部,伪装成浏览器:

user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
request.add_header('User-Agent', user_agent)

服务器可能会检查的头部如下:

  • User-Agent : 有些服务器或 Proxy 会通过该值来判断是否是浏览器发出的请求
  • Content-Type : 在使用 REST接口时,服务器会检查该值,用来确定 HTTP Body 中的内容该怎样解析。常见的取值有:
    • application/xml : 在 XMLRPC,如 RESTful/SOAP 调用时使用
    • application/json : 在 JSON RPC 调用时使用
    • application/x-www-form-urlencoded : 浏览器提交 Web 表单时使用

三,网页img标签中属性不同

网页爬虫中核心的步骤就是读取并解析网页内容,通过正则表达式匹配自己想要获取的内容,再下载到本地或者存入数据库中。

如果有朋友对于正则表达式不太了解,可以参加下面的博客,也是上面博客中引用的文章,讲解还是很明白的:

正则表达式介绍

而运行了他所给的网页后发现是可以的,但是换了其他网页爬图片时发现并不能下载,于是我将函数中的imglist集合打印了出来,看到是空的,可以猜测到是由于正则表达式出了问题,匹配不到了,通过查看器查看其他网页图片的源码发现有些src属性后面跟的是width属性,有的是size属性,还有的是pic_ext属性,所以只能改变正则表达式同时适配这几种才行:

reg = r'src="(http://.+?\.jpg|ng)" [size|width|pic_ext]'
imgre = re.compile(reg)
imglist = imgre.findall(html)

这里要提一下的是,findall所匹配的是元组也就是圆括号中的元素,每一个圆括号就代表一个元组(ps:这是我个人的理解,并没有在其他地方找到确切说明,但是多次尝试的确是这样)

四,urlretrieve的使用

x = 0
for imgurl in imglist:
    urllib.request.urlretrieve(imgurl, '%s.jpg' % x, reporthook)
    x += 1

开始写的时候urlretrieve我只用了2个参数,是没有最后一个的,这是在网上找资料时发现的,后来查了api才知道urlretrieve参数列表是这样的:

urllib.urlretrieve(url, filename=None, reporthook=None, data=None)
参数说明:

  • url:外部或者本地url
  • filename:指定了保存到本地的路径(如果未指定该参数,urllib会生成一个临时文件来保存数据);
  • reporthook:是一个回调函数,当连接上服务器、以及相应的数据块传输完毕的时候会触发该回调。我们可以利用这个回调函数来显示当前的下载进度。
  • data:指post到服务器的数据。该方法返回一个包含两个元素的元组(filename, headers),filename表示保存到本地的路径,header表示服务器的响应头。

从上面的列表可以看出来后面三个是默认参数,当不传参的时候就为None,这个reporthook主要作用是显示下载进度,代码如下:

def reporthook(a, b, c):
    """
       a:已经下载的数据块
       b:数据库块的大小
       c:远程文件的大小
    """
    per = 100.0 * a * b / c
    if per > 100:
        per = 100
        print('完成!')
    print('%.2f%%' % per)

整体代码:

import re
import urllib.request


def reporthook(a, b, c):
    """
       a:已经下载的数据块
       b:数据库块的大小
       c:远程文件的大小
    """
    per = 100.0 * a * b / c
    if per > 100:
        per = 100
        print('完成!')
    print('%.2f%%' % per)


def get_html(url):
    request = urllib.request.Request(url)
    # 添加头部,伪装成浏览器
    user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
    request.add_header('User-Agent', user_agent)

    response = urllib.request.urlopen(request)
    html = response.read()
    return html


def get_img(html):
    html = html.decode('utf-8')
    reg = r'src="(http://.+?\.jpg|ng)" [size|width|pic_ext]'
    imgre = re.compile(reg)
    imglist = imgre.findall(html)
    print(imglist)

    x = 0
    for imgurl in imglist:
        urllib.request.urlretrieve(imgurl, '%s.jpg' % x, reporthook)
        x += 1
    return 'done'


html = get_html('http://tieba.baidu.com/p/2460150866')
print(get_img(html))

以上很多都是个人见解,有什么不对的还望大牛指点。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值