• Python 爬取网站资源文件


    爬虫原理:

    以下来自知乎解释

    首先你要明白爬虫怎样工作。
    想象你是一只蜘蛛,现在你被放到了互联“网”上。那么,你需要把所有的网页都看一遍。怎么办呢?没问题呀,你就随便从某个地方开始,比如说人民日报的首页,这个叫initial pages,用$表示吧。
    在人民日报的首页,你看到那个页面引向的各种链接。于是你很开心地从爬到了“国内新闻”那个页面。太好了,这样你就已经爬完了俩页面(首页和国内新闻)!暂且不用管爬下来的页面怎么处理的,你就想象你把这个页面完完整整抄成了个html放到了你身上。
    突然你发现, 在国内新闻这个页面上,有一个链接链回“首页”。作为一只聪明的蜘蛛,你肯定知道你不用爬回去的吧,因为你已经看过了啊。所以,你需要用你的脑子,存下你已经看过的页面地址。这样,每次看到一个可能需要爬的新链接,你就先查查你脑子里是不是已经去过这个页面地址。如果去过,那就别去了。
    好的,理论上如果所有的页面可以从initial page达到的话,那么可以证明你一定可以爬完所有的网页。

    链接:http://www.zhihu.com/question/20899988/answer/24923424

    1.爬取一个匿名可访问upload目录的网站
    import re,os
    import urllib.request
    import urllib
    import ssl
    
    ssl._create_default_https_context = ssl._create_unverified_context
    
    from collections import deque
    
    queue = deque()
    visited = set()
    
    origurl=url = 'http://www.***.cn/Upload/'  # 入口页面, 可以换成别的
    path = 'C:/Users/Administrator/Desktop/a/'
    
    queue.append(url)
    cnt = 0
    
    while queue:
        url = queue.popleft()  # 队首元素出队
    
        print('已经抓取: ' + str(cnt) + '     正在抓取 <---    ' + url)
        cnt += 1
        try:
            urlop = urllib.request.urlopen(url, timeout=3)
        except:
            continue
    
        if 'image' in urlop.getheader('Content-Type'):
            xpath=url.replace(origurl,'')
            orig_list=xpath.split("/")
            orig_ext_file = orig_list[-1]
            path_sub = orig_list[:-1]
            new_path=path+('/'.join(path_sub))
            try:
                os.makedirs(new_path)
            except Exception as e:
                print(e)
    
            urllib.request.urlretrieve(url, new_path+'/'+orig_ext_file)
    
        if 'html' not in urlop.getheader('Content-Type'):
            continue
    
        # 处理异常
        try:
            data = urlop.read().decode('utf-8')
        except:
            continue
    
        # 正则表达 提取页面中所有队列, and判断or访问过, too加入待爬队列
        linkre = re.compile('href="(.+?)"')
        for x in linkre.findall(data):
            if re.match(r"?C=.", x):
                continue
            if re.match(r"/Upload/", x):
                continue
    
            if x not in visited:
                queue.append(url + x)
                visited |= {url}  # 标记为已访问
                print('加入队列 --->    ' + x)

    2.抓取一个美图高清壁纸网站

    import re
    import urllib.request
    import urllib
    import ssl
    
    ssl._create_default_https_context = ssl._create_unverified_context  # 取消ssl验证https://
    
    from collections import deque
    
    queue = deque()
    visited = set()
    
    website = 'http://www.***.com/'
    website_column = 'column/'
    url = website + website_column + '80827.html'  # 入口页面
    path = './images/'
    
    queue.append(url)  # 加入队列
    cnt = 0
    while queue:
        url = queue.popleft()  # 队首元素出队
        visited |= {url}  # 已访问
    
        print('已经抓取: ' + str(cnt) + '     正在抓取 <---    ' + url)
        cnt += 1
        try:
            urlop = urllib.request.urlopen(url, timeout=3)
        except:
            continue
        current_num_re = re.compile(r'/' + website_column + '(d+)/')
        current_num = current_num_re.findall(url)
        if url == website + website_column:
            continue
        if 'html' not in urlop.getheader('Content-Type'):
            continue
    
        # 处理异常
        try:
            data = urlop.read().decode('gbk')
        except:
            try:
                data = urlop.read().decode('utf-8')
            except:
                continue
    
        # 正则表达 提取页面中所有队列, and判断or访问过, too加入待爬队列
        linkre = re.compile('href="(.+?)"')
        inside1 = re.compile(r'/' + website_column + '(.*)')
        inside2 = re.compile(r'(d+).htm')
    
        for x in linkre.findall(data):
            if 'http' not in x and x not in visited:
                resulturl = ''
                c = inside1.findall(x)
                if c:
                    resulturl = website + website_column + c[0]
                else:
                    c = inside2.findall(x)
                    if c:
                        cnum = ''
                        cnum = current_num[0] if current_num else ''
                        resulturl = website + website_column + cnum + '/' + c[0] + '.htm'
    
                if resulturl:
                    queue.append(resulturl)
                    print('加入队列 --->    ' + resulturl)
    
        linkrerr = re.compile('<p><img src="(.*)" onload="btnaddress(1);')
        src = linkrerr.findall(data)
        if src:
            print(src)
            req = urllib.request.Request(src[0], headers={
                'Connection': 'Keep-Alive',
                'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
                'Accept-Language': 'en-US,en;q=0.8,zh-Hans-CN;q=0.5,zh-Hans;q=0.3',
                'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko',
                'Referer': url
            })
            resource = urllib.request.urlopen(req, timeout=30)
            orig_list = src[0].split("/")
            orig_ext_file = orig_list[-1]
            path_sub = orig_list[:-1]
            # urllib.request.urlretrieve(src[0], path  + orig_ext_file)  #网站拒绝爬虫使用Referer 时, urlretrieve无法下载
            foo = open(path + orig_ext_file, "wb")
            str = resource.read()
            foo.write(str)
            foo.close()

    参考地址: https://jecvay.com/2014/09/python3-web-bug-series1.html

  • 相关阅读:
    建造者模式
    模板方法模式
    抽象工厂模式
    工厂方法模式
    Josephus环问题
    单例模式
    求两个数的最大公约数
    Nginx的安装与部署
    左京大夫显辅
    java 调用第三方系统时的连接代码-记录
  • 原文地址:https://www.cnblogs.com/dcb3688/p/4607985.html
Copyright © 2020-2023  润新知