Python爬虫实战 requests+beautifulsoup+ajax 爬取半次元Top100的cos美图

1.Python版本以及库说明

Python3.7.1 Python版本
urlencode 可将字符串以URL编码,用于编码处理
bs4 解析html的利器
re 正则表达式,用于查询页面的一些特定内容
requests 得到网页html、jpg等资源的lib
os 创建文件夹需要用到系统操作lib
time 时间模块,获取日期建立文件夹
html5lib 解析模块
lxml 解析模块
multiprocessing 多线程模块

2.IDE

Pycharm

3.浏览器页面检查工具

QQ浏览器

4.爬虫抓取过程分析

4.1https请求的uesr_head参数设置

agent = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 ' \
        '(KHTML, like Gecko) Chrome/63.0.3239.26 ' \
        'Safari/537.36 Core/1.63.6721.400 QQBrowser/10.2.2243.400'
headers = {
    'user-agent': agent

4.2分析top100列表页面(利用ajax获得全部数据)

页面地址是https://bcy.net/coser/toppost100

进入页面发现只有前30名的图片,但当我们下拉可以发现,页面动态加载了全部的COS图,利用页面检查功能 我们分析这是一个ajax请求,我们可以通过构造ajax请求来获得全部图片

我们打开页面检查工具,选择Network,然后在选择XHR,也就是ajax的核心——XMLHttpRequest对象,我们看到初始页面仅有两个文件,下拉使会产生新的文件,我们查看新文件的Query String Parameters可以发现其发送了一组json数据

        'p': 2,   
        'type': 'week',
        'data': ''

我们可以推断p应该代表页码,type应该代表这是本周热门的数据

我打算通过构造url直接获取数据时发现页面404,这也是我对与前端以及ajax不熟悉的原因吧

    params = {
        'p': page,
        'type': 'week',
        'data': ''
    }
    base_url = 'https://bcy.net/coser/toppost100'
    url = base_url + urlencode(params)

查了查资料,也不是很懂,最后我直接XHR产生的新文件,顿时醒悟,我来到了这样的页面

我们看到页面的url是https://bcy.net/coser/index/ajaxloadtoppost?p=2&type=week&date=
自己手动修改p=2中的值就可以获得图片的页面了

4.3soup对象查找源代码中的链接

首先查找li标签

all_li = soup.find_all('li', class_=re.compile('js-smallCards _box'))

然后查找li的标签中的a标签 提取href

    urls = []
    for li in all_li:
        a = li.find('a')
        urls.append(a['href'])
    return urls

4.4进入页面链接,遍历读取所有图片

一开始还想继续利用soup进行解析,发现python读取页面后并没有找到那些标签,一度再次陷入困境,最后在js文件中发现了想要的数据

我们发现图片路径都是类似的

\"path\":\"https:\\u002F\\u002Fimg-bcy-qn.pstatp.com\\u002Fuser\\u002F2511464\\u002Fitem\\u002Fc0juk\\u002F0ed91266f72b4f73b5f4bfec1c0ebac0.jpg\\u002Fw650\"

(这部分中应该有关于编码解码还有路径名的一些东西,但我还不是很熟悉)
我们可以利用re正则表达式模块提取path
设定头部path尾部w650

    pattern = re.compile('"path(.*?)w650', re.S)
    items = re.findall(pattern, content)

对其中的\u002F进行替换,去掉尾部的\w650,得到正确的url

for i in range(len(items)):
    items[i] = items[i].replace(r'\\u002F', '/')
    items[i] = items[i][5:-1]

其他步骤应该就没有什么问题了

4.5建立文件夹分类下载存储图片

获取标题,以标题为名建立文件夹,需要去掉非法的一些符号

soup = BeautifulSoup(content, 'html5lib')
title = soup.title.string
unvalid_str = '<>,\/|,:,"",*,?'
for ch in unvalid_str:
    title = title.replace(ch, '')

4.6尝试多线程进行爬取提高速度

    pool = Pool()
    # 一共6组ajax请求
    groups = ([x+1 for x in range(6)])
    # map()实现多线程下载
    pool.map(main, groups)
    # 关闭
    pool.close()
    # 如果主线程阻塞后,让子进程继续运行完成之后,在关闭所有的主进程
    pool.join()

4.7最终结果展示




5.Github项目地址

https://github.com/hlcoxndgw/BanciyuanBcyTopCosplaySpider

欢迎大家star

6.总结

  • 半次元网站应该没有什么反爬虫的措施,所有在代码也没有进行IP代理或者抓取等待的设置
  • COS原图文件还是很大的,爬取TOP100的所有图片应该需要很多的流量(我爬取完成发现文件夹大小是6GB。。。)
  • 一些COSer设置了仅对粉丝可见,没有对这种情况进行处理,所有这种情况会得到一个空文件夹
  • 网站页面内容随时可能变化,导致代码无法运行,但爬取的原理基本不会变化
  • 第一次写博客,可能存在许多问题,有什么不足的地方或者有什么疑问都可以在评论区指出,谢谢大家

猜你喜欢

转载自blog.csdn.net/weixin_43753772/article/details/84405367