zl程序教程

您现在的位置是:首页 >  后端

当前栏目

Python 爬取网站资源文件

2023-09-11 14:17:02 时间

爬虫原理:

以下来自知乎解释

首先你要明白爬虫怎样工作。
想象你是一只蜘蛛,现在你被放到了互联“网”上。那么,你需要把所有的网页都看一遍。怎么办呢?没问题呀,你就随便从某个地方开始,比如说人民日报的首页,这个叫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