光速入门python编写爬虫

前言

如下是成果图。通过爬虫爬取到的图片。不过后面准备通过API接口把它整个站点图片爬下来的时候,网址数据库凉了,也不知道是不是我的原因(哭)

好吧,我觉得必须说一下,这个目标网址我是通过一篇教程中看到的,索性直接拿来用哈哈哈并没有其他想法!

image.png
截图的时候代码并不完整。

杂七杂八的知识

格式化

下述代码以%为开头的占位符对数据进行了‘替换’操作。%s 为 字符串 ,%d 为整数。实际上我们平常都是操作字符串吧?记住一个%s就行了~

'Hi, %s, you have $%d.' % ('Michael', 1000000)
'Hello, {0}, 成绩提升了 {1:.1f}%'.format('小明', 17.125)


List、tuple、dict

list[1,2,3] 

上述代码便直接建立了一个list,list是支持变化的,所以可以使用下面三种常用操作 .append() 追加到末尾 、.insert(i)插入 、.pop(i) 删除 。

并且支持多种类型同时存在、也可以在list中嵌套list,实现多维数组 。

tuple(1,)

tuple与list的差别是,它一旦定下来就不允许进行更改。

dict = {'Michael': 95, 'Bob': 75, 'Tracy': 85} 
dict.get(key) //获得key
'Tracy' in dict //判断key是否存在

dict使用键值对进行存储,如果要存储的数据非常大,那么应该使用dict进行。它所采用的是根据字母的索引表进行查询,这样速度远远快于List与tuple。

循环(迭代)

python中的for最重要的是可以对所有可迭代对象进行遍历,如上述所讲的List、tuple、dict都可以。 不过dict由于以字母索引表排列的原因,遍历出的数据可能与插入时的顺序并不相同。

names = ['a','b','c']
for name in names:
    print(name)

while没什么好说的,如果为真就循环。

sum = 0
while sum<=5:
    sum =sum+1

切片

python中的切片特性非常好用,可以很灵活的取出list中的数据。

n = [1,2,3,4,5]
n[0:3]  //取从0位到3位的数据,结果是:[1,2,3]
 [-2:]  //取最后两位的值。第一个索引是0,最后一个是-1。

requests与re

实际上这个没什么好记录的,无非就是简单的post和get。

requests.get(url, headers=headers)
requests.post(urll, headers=headers, data=data)

不过值得记录的是,在requests访问网页的时候会在headers中写入requests的特征。因此很多网站的反爬虫机制当碰到这样的headers会屏蔽掉访问请求。

所以在这里我们需要在.get参数中改一下headers。

headers = {
    "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
                  "Chrome/78.0.3904.108 Safari/537.36 "
}

而data数据是以对象形式加载的。

    data = {
        'append': 'list-archive',
        'paged': 'paged',
        'action': 'ajax_load_posts',
        'query': '18',
        'page': 'cat'
    }

获得数据后,通过.text得到返回值,接下来就需要re库进行解析返回的数据了。re是一个使用正则表达式匹配字符串的库。

findall()匹配所有对象 search()匹配第一个对象。

re.findall(' <a href="(.*?)" class="list-title text-md h-2x" target="_blank">', Html)

通过上述代码就可以得到这个a标签的href属性。findall函数会通过(.*?)左右的字符串进行匹配之间的数据。这是一个简单的正则表达式。

OS库与I/O操作

OS库包括路径操作、进程管理等功能。这里用到了

op.exists(路径)    // 判断path对应文件或目录是否存在,返回True或False
os.mkdir(文件夹名)  //创建一个文件夹

下面代码是对name文件进行一个写入。实际上本来读写操作使用open就行了,但是这个操作可能会出现异常,我们必须要抛出异常。所以通过with。

而open参数中的‘w’是指写入一个文件,如果是'r'便是读取文件。简单的说,打开一个name文件,如果不存在那么就创建一个,创建后将这个对象赋给f,然后f通过writer函数进行写入r1中的内容。

with open(name, 'w') as f:
     f.write(r1.content)

完整的爬虫代码

import requests
import re
import os

headers = {
    "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
                  "Chrome/78.0.3904.108 Safari/537.36 "
}


def getUrl(paged):
    data = {
        'append': 'list-archive',
        'paged': paged,
        'action': 'ajax_load_posts',
        'query': '18',
        'page': 'cat'
    }
    r = requests.post('https://www.vmgirls.com/wp-admin/admin-ajax.php', headers=headers, data=data)
    Html = r.text
    print(Html)
    r1 = re.findall(' <a href="(.*?)" class="list-title text-md h-2x" target="_blank">', Html)

    print('第' + str(paged) + '页的数量:' + str(len(r1)))
    for url in r1:
        getImg(url)


def getImg(param):
    r = requests.get(param, headers=headers)
    Html = r.text
    urls = re.findall('data-src="https://(.*?)" data-', Html)
    dirs = re.findall('h1 class="post-title h3">(.*?)</h1>', Html)[-1]
    print(dirs)
    if not os.path.exists(dirs):
        os.mkdir(dirs)
    for url in urls:
        name = url.split('/')[-1]
        r1 = requests.get('http://' + url, headers=headers)
        if name != "rss.png":
            with open(dirs + "/" + name, 'wb') as f:
                f.write(r1.content)


def main():
    paged = input('获取多少页:')
    n = 1
    while n <= int(paged):
        getUrl(str(n))
        n = n + 1
    print('任务完成')


main()

# python