2018年3月4日星期日

【Python】从爬虫开始吧——爬取妹子图整站

首先得解决环境和工具的问题
Python基础教程
Python3基础教程
大家也可以去慕课网看视频学习哦,关于选择Python2还是Python3的问题,上手的话还是直接选择3吧。

关于爬虫

爬虫就是在互联网中执行爬取有用信息的程序,总的工作流程如下:
找到爬虫入口->获取目标链接->下载网页-> 解析网页 -> 获取价值信息 ->存库(文件保存)操作
首先给自己一个伟大的小目标吧!或许明天的UC头条就是,震惊!一16岁编程奇才爬取某社区2亿条用户数据。这里写图片描述

开始吧

我们的目标就从一个图片网站开始吧,坐好啦,老司机要发车了 –> mzitu.com
这里写图片描述
http://www.mzitu.com/all 每日更新页面给了我们一个很好的爬虫入口,良心站长,F12进入浏览器调试模式,更方便开发人员观察
这里写图片描述
这里写图片描述
找到入口和目标链接之后开始下载网页
# -*- coding: UTF-8 -*-
from urllib import request

#目标抓取网页
src = 'http://www.mzitu.com/all'
#浏览器请求头(大部分网站没有这个请求头可能会报错)
mheaders = {'User-Agent':"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1"}

#读取一个网页
def getHtml(url):
    req = request.Request(url,headers=mheaders) #添加headers避免服务器拒绝非浏览器访问
    page = request.urlopen(req)
    html = page.read()
    return html.decode('utf-8')  # python3 python2版本直接返回html

print(getHtml(src))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

urllib.request.urlopen()请求你个网页,是不是so easy,各位看官,你老厉害了。
拿到这个入口网页之后,我们顺着主线走,不要迷路了,那么入口网页里面用有的价值是什么了,当然是妹子,恩我们要奔着套路地址去,这里我们需要用到beautifulsoup4 ,当然高手一般都是使用正则表达式的,可是菜鸟真的合适吗,虽然bs4效率低一点,但是对开发人员友好啊。获取bs4方法,前提是你需要配置好python和pip(pip工具是python自带的)的环境变量,这里不赘述了
pip install beautifulsoup4
好了,继续前行吧。去拿到我们的子目标,首先我们得明确子目标

# -*- coding: UTF-8 -*-
from urllib import request
from bs4 import BeautifulSoup

#目标抓取网页
src = 'http://www.mzitu.com/all'
#浏览器请求头(大部分网站没有这个请求头可能会报错)
mheaders = {'User-Agent':"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1"}

#读取一个网页
def getHtml(url):
    req = request.Request(url,headers=mheaders) #添加headers避免服务器拒绝非浏览器访问
    page = request.urlopen(req)
    html = page.read()
    return html.decode('utf-8')  # python3 python2版本直接返回html

#从入口爬取所有的目标链接
def getallUrl(html):
    #构造一个bs对象
    soup = BeautifulSoup(html, 'html.parser')
    #使用bs对象寻找class为all的div 然后再寻找这些div里面的a标签,可能我们需要多试几次才能准确的get
    all = soup.find('div',class_='all').find_all('a')
    for li in all:
        print(li)

getallUrl(getHtml(src))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
这里写图片描述
行了,我们又有目标了,遍历这些目标,最后在子目标里面寻找最终目标,对最终目标进行存库(文件操作)即可完成我们这次探险了!

最后一段旅程需要各位生手自行探索,老衲先行告退。对了,地图拿走不谢:
# -*- coding: UTF-8 -*-
from urllib import request
from bs4 import BeautifulSoup
import uuid
import time

#目标抓取网页
src = 'http://www.mzitu.com/all'
#浏览器请求头(大部分网站没有这个请求头可能会报错)
mheaders = {'User-Agent':"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1"}

#读取一个网页
def getHtml(url):
    req = request.Request(url,headers=mheaders) #添加headers避免服务器拒绝非浏览器访问
    page = request.urlopen(req)
    html = page.read()
    return html.decode('utf-8')  # python3 python2版本直接返回html

#从入口爬取所有的目标链接
def getallUrl(html):
    #构造一个bs对象
    soup = BeautifulSoup(html, 'html.parser')
    #使用bs对象寻找class为all的div 然后再寻找这些div里面的a标签,可能我们需要多试几次才能准确的get
    all = soup.find('div',class_='all').find_all('a')
    print(len(all))#无聊打印点什么
    for li in all:
        subSrc = li.attrs['href']
        subHtml = getHtml(subSrc)
        subSoup = BeautifulSoup(subHtml, 'html.parser')
        page = subSoup.find('div', class_='pagenavi').find_all('span')
        #page[-2]是表示数组从右(末端数2个) maxpage拿到套图最后一页
        maxPage = page[-2].get_text()
        i = 1
        while (i <= int(maxPage)):
            time.sleep(0.08) #休息0.08s,防止服务器拒绝频繁请求
            tagetSrc = subSrc + '/' + str(i)
            tagetHtml = getHtml(tagetSrc)
            tagetSoup = BeautifulSoup(tagetHtml, 'html.parser')
            img = tagetSoup.find('div', class_='main-image').find('img')
            print(time.time())#无聊打印点什么
            #uuid()构造一个世界唯一字符串,为了防止文件重名
            name = img.attrs['alt'] + str(uuid.uuid4())
            imgsrc = img.attrs['src']
            print(imgsrc + "-----" + name)#无聊打印点什么
            try:
                #这里的指定存储路径,需要注意的是这里需手动创建文件夹,如需自动想、可以使用os库
                request.urlretrieve(imgsrc, 'D:\\meizi\\' + '%s.jpg' % name)  # 指定目录位置
            except BaseException:
                #捕获异常情况
                print('Error:there is something wrong!')
                # 遇到IOError: [Errno socket error] [Errno 10060]服务器拒绝频繁访问 阻塞1s
                time.sleep(1)
                try:
                    request.urlretrieve(imgsrc, 'D:\\meizi\\' + '%s.jpg' % name)  # 指定目录位置
                except BaseException:
                    print('Error:there is something wrong!over')
            # print(tagetSrc)
            i += 1
        print('end')
#开始
print('begin')
getallUrl(getHtml(src))
#结束
print('over')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
成果

好了,这次旅行到此结束,对于这次初次旅程还满意吗?给各位老厉害的看官留几个宝箱吧:
1.这种方式爬取数据存在什么弊端?该怎么完善?
2.有什么方法提高爬取效率?
3.反面思考我们的web网站怎么防止被机器爬取数据?
4.我们的爬虫(机器)面对验证码,登录等问题怎么处理?

最后

谢谢站长

没有评论:

发表评论

注意:只有此博客的成员才能发布评论。

Also Read: