爬虫日记1


前言

一直想学爬虫来着,做做脚本什么的,还顺路还可以学点html基础,扩展点技术栈,以下是自己做的笔记和实践,
目前看的是 这个 ,关于爬虫的一个比较入门的视频,主要的学到的库有 requests re bs4 后面的scrapy感觉讲的泛泛没有仔细看,都用 pip intall requests安装即可,re库是python标准库不用额外安装。
主要是非动态生成的网页爬取,并且只爬取html页面信息,如果有关数据封在了json里那搞不定
说白了就是一些字符串的分析,结合了re或者利用bs4帮助分析。


Requests 库

模拟用户行为向服务器发送请求,主要函数就是requests.method() 有七个method函数,常用的就get和head两种,我觉得delete很有意思,应该不会有哪个缺心眼的允许用户可以随意更改自己html上的资源吧,几个方法其实都是都是request方法封装的,可以直接调用request方法然后第一个传参写一下就好,但我觉得麻烦。
上一个图:
可以看到是互通的
贴一个标准爬取的模板,用try except结构保证异常不跳出,也可以自己if检查request.status(),如果状态码不是200那就是有问题,但是这方法不如tryexcept结构

def template_get():
    try:
        user_agent={'user-agent':'Chrome/10'}
        search = {'k':'xbox'}
        web = requests.get(headers=user_agent,url=r'https://www.amazon.de/s',params=search)
        web.raise_for_status()
        web.encoding=web.apparent_encoding #这段的意思是把信息的解码方式定义一下,否则可能会出现无法正常显示的字符
        									#一般来说apparent encoding比较准
        return web.text
    except:
        return 'ERROR'

另外这个用到了get里关于paramshead的应用,

1.headers重写了申请里关于设备user_agent的描述,简单的绕过了反爬
2.params参数则加上了上边定义的search键值对,达到了对url的扩充,从而实现搜索功能,因为亚马逊的搜索api是/s, 同理要爬取的网页可以看一看对应的搜索api是什么
3.web.encoding=web.apparent_encoding 这一句对一些已知的网页,或者同时爬取某个网站同类型网页时,可以提前查看下,或者先爬一个网页知道解码方式,后续可以手动指定来获取更快的解析速度,因为apparent_encoding方法会对text解析,耗时会“”较长"
4.就是网页的html内容,即源代码,如果需要爬取的内容在这里面可以考虑使用bs4库继续html语法结构解析或者用re库使用正则表达式直接匹配,或者两个结合使用,反正就是对文本的筛选和分析

再一个比较常见的例子,爬图片

def template_getImage():
    try:
        user_agent = {'user-agent': 'Chrome/10'}
        path = './saved.jpg'
        web = requests.get(headers=user_agent,
                           url=r'https://blob.keylol.com/forum/202109/11/233847wk2iuua26oo0i8i8.jpg')
        web.raise_for_status()
        web.encoding = web.apparent_encoding
        with open(path, 'wb') as f:
            f.write(web.content)
    except:
        return 'ERROR'

这个例子主要是用到了返回的request对象下content属性,用request库返回的对象有很多属性,比如上个例子的text,这个就用到了内容属性,也就是二进制的东西,把它写成图片,因为有后缀名限定,并且content的内容里也有关于jpg编码的东西,可以打印看看

bs4 库

自己写一个爬取当前页面所有图片的demo来介绍下bs4库

def getHTMLtext(url):
    try:
        user_agent = {'user-agent': 'Chrome/10'}
        search = {'k': 'xbox'}
        web = requests.get(headers=user_agent, url=url)
        web.raise_for_status()
        web.encoding = web.apparent_encoding
        return web.text
    except:
        return 'ERROR'
        
def savetImage(image_url):
    try:
        user_agent = {'user-agent': 'Chrome/10'}
        name = image_url.split('/')[-1]
        prefix, sufix = name.split('.')[-2], name.split('.')[-1][:3]
        path = f'./{prefix}.{sufix}'
        web = requests.get(headers=user_agent,
                           url=image_url)
        web.raise_for_status()
        web.encoding = web.apparent_encoding
        with open(path, 'wb') as f:
            f.write(web.content)
        return 'Done'
    except:
        return 'ERROR'

def template_getImage2(text):
    soup = BeautifulSoup(text, 'html.parser')
    for link in soup.find_all('img'):
        image_url = link.get('file')
        if image_url is None:
            continue
        try:
            print(savetImage(image_url))
        except:
            print(f'ERROR AT {image_url}')

if __name__ == '__main__':
    url = r'https://keylol.com/t748192-1-1'
    if url
    demo = getHTMLtext(url)
        if demo !='ERROR':
        template_getImage2(demo)

首先看一眼源码发现楼里的图都在img这个标签下,再具体一点就是img下的file键值对,分析完毕就好办了,大概流程如此:
(获取源码即requests库的东西,不赘述)
首先摘出来所有img标签: for link in soup.find_all('img'):
接着提取里面的键值对: image_url = link.get('file')
然后分析名字用原名保存 : prefix, sufix = name.split('.')[-2], name.split('.')[-1][:3]
别忘了加一些异常判断保证遇到空或者出错时程序不跳出

优化一下

可以看到这个帖子有好多页,怎么实现自动翻页功能呢?首先肯定是要对帖子链接'https://keylol.com/t748192-1-1'进行分析
很容易的我们发现这个帖子页数是根据最后-1-1进行储存的那这就好办了,很快啊,就想到一个很直接的思路:
爬完一页然后尝试爬下一页
行就爬,不行就中断结束
具体操作为:

if __name__ == '__main__':
    url_prefix = r'https://keylol.com/t748192'
    page_nr = 1
    page_limt = 999
    while page_limt > page_nr:
        page = f'-{page_nr}-1'
        url = url_prefix + page
        print(url)
        demo = getHTMLtext(url)
        if demo != 'ERROR':
            template_getImage2(demo)
            page_nr += 1
        else:
            print('end')
            break

除此之外也可以在request.get函数中更改param的值,都是一样的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值