鱼C论坛

 找回密码
 立即注册
查看: 660|回复: 15

[已解决]求教此网站的Ajax该如何处理?

[复制链接]
发表于 2020-6-17 13:53:08 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
URL:https://www.umtuba.com/
我之前做过这个站点的整站爬取程序

今天进来发现改版了,需要点击加载更多,才出现Ajax的加载,而我都还不会甚至从来没做过这样的爬虫
请教各位前辈,这个站点需要如何爬取,我需要补充哪些知识点
如果你有详细解说小弟不甚感激!

谢谢!
最佳答案
2020-6-17 17:29:51
查看【浏览器f12】-【网络】-【参数】就能看出每次ajax的参数,主要是page变动了,从0-n变动,所以request时把page参数变一下即可。
url = 'https://www.umtuba.com/wp-admin/admin-ajax.php'
headers = {'User-Agent': 'firefox', 'X-Requested-With': 'XMLHttpRequest'}
# 页码数据
data = {'action': 'postlist_newajax', 'id': '0', 'type': 'index'}
# 存储图集的url
result = []
# 爬5页的图片url,可以根据自己需要修改。
num = 5
for item in range(num):
    data['paged'] = item
    r = requests.post(url, headers=headers, data=data)
    j_data = r.json()
    result.extend(re.findall(r'href="(.*?)"', str(j_data)))
print(result)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-6-17 17:29:51 | 显示全部楼层    本楼为最佳答案   
查看【浏览器f12】-【网络】-【参数】就能看出每次ajax的参数,主要是page变动了,从0-n变动,所以request时把page参数变一下即可。
url = 'https://www.umtuba.com/wp-admin/admin-ajax.php'
headers = {'User-Agent': 'firefox', 'X-Requested-With': 'XMLHttpRequest'}
# 页码数据
data = {'action': 'postlist_newajax', 'id': '0', 'type': 'index'}
# 存储图集的url
result = []
# 爬5页的图片url,可以根据自己需要修改。
num = 5
for item in range(num):
    data['paged'] = item
    r = requests.post(url, headers=headers, data=data)
    j_data = r.json()
    result.extend(re.findall(r'href="(.*?)"', str(j_data)))
print(result)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-6-17 20:40:28 | 显示全部楼层
suchocolate 发表于 2020-6-17 17:29
查看【浏览器f12】-【网络】-【参数】就能看出每次ajax的参数,主要是page变动了,从0-n变动,所以request ...

真棒的解答,很适合学习的答案.
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-6-17 20:45:06 | 显示全部楼层
suchocolate 发表于 2020-6-17 17:29
查看【浏览器f12】-【网络】-【参数】就能看出每次ajax的参数,主要是page变动了,从0-n变动,所以request ...

哎?获取到的每一条URL都重复了一次
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-6-17 20:47:08 | 显示全部楼层
nanrenne 发表于 2020-6-17 20:45
哎?获取到的每一条URL都重复了一次

哦哦,确实 ,在源文件中就出现了2此
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-6-17 21:02:06 | 显示全部楼层
nanrenne 发表于 2020-6-17 20:47
哦哦,确实 ,在源文件中就出现了2此

这个我没注意,你可以用set去重:
result = set(result)
result = list(result)
print(result)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-6-17 21:53:07 | 显示全部楼层
suchocolate 发表于 2020-6-17 21:02
这个我没注意,你可以用set去重:

谢谢,之前我也这么用,后来发现他会乱序,改了一下正则,目前好啦.十分感谢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-6-18 11:19:44 | 显示全部楼层
suchocolate 发表于 2020-6-17 21:02
这个我没注意,你可以用set去重:

抓取到有些地方匹配还是出错了,请问大佬
    headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36'}
    picnamezz = re.compile('点击图片.*?alt="(.*?)" width',re.S)
    picname = re.findall(picnamezz,content)
    print('该图片名称为:',picname[0])

    jpgnow = re.compile('点击图片查看.*?<img src="(.*?)" alt="' + r'picname[0]',re.S)#正则中添加变量的方式

以上的jpgnow的正则匹配就是不对,我第一次从正则内添加变量,可是这样匹配不到为什么呢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-6-18 12:54:57 | 显示全部楼层
本帖最后由 suchocolate 于 2020-6-18 12:57 编辑

正则比较麻烦,还是建议用xpath,给你写了一个整个网站的爬虫,不过这个网站慢,建议数字改小:
import requests
import re
from lxml import etree
import os


def ck_dir():
    if not os.path.exists('pic'):
        os.mkdir('pic')


def get_album_list(num):
    firstpage_url = 'https://www.umtuba.com/wp-admin/admin-ajax.php'
    data = {'action': 'postlist_newajax', 'id': '0', 'type': 'index'}
    # 存储图集的url
    result = []
    for item in range(num):
        data['paged'] = item
        r = requests.post(firstpage_url, headers=headers, data=data)
        j_data = r.json()
        result.extend(re.findall(r'href="(.*?)"', str(j_data)))
    result = set(result)
    result = list(result)
    return result


def get_pics_list(plist, url, num):
    baseurl = url.replace('.html', '')
    for x in range(2, num + 1):
    # for x in range(2, 5):
        r = requests.get(baseurl + '_' + str(x) + '.html', headers=headers)
        html = etree.HTML(r.text)
        result = html.xpath('//img[contains(@class, "alignnone")]/@src')
        plist.extend(result)
    return plist


def ana_album(alist):
    m = 1
    for item in alist:
        r = requests.get(item, headers=headers)
        html = etree.HTML(r.text)
        picname = html.xpath('//h1/text()')[0][11:]
        # print(picname)
        lastpagenum = html.xpath('//a[@title="最后页"]/text()')
        # print(lastpagenum)
        piclist = html.xpath('//img[contains(@class, "alignnone")]/@src')
        # print(piclist)
        piclist = get_pics_list(piclist, item, lastpagenum)
        n = 1
        for x in piclist:
            r = requests.get(x, headers=headers)
            with open('pic\\' + picname + '_' + str(n) + '.jpg', 'wb') as f:
                f.write(r.content)
            print(picname + '_' + str(n) + '.jpg下载完成, 共下载' + str(m) + '张图片。')
            n = n + 1
            m = m + 1


if __name__ == '__main__':
    headers = {'User-Agent': 'firefox', 'X-Requested-With': 'XMLHttpRequest'}
    num = 5
    ck_dir()
    album_list = get_album_list(num)
    ana_album(album_list)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-6-18 13:55:51 | 显示全部楼层
suchocolate 发表于 2020-6-18 12:54
正则比较麻烦,还是建议用xpath,给你写了一个整个网站的爬虫,不过这个网站慢,建议数字改小:

十分感谢,我也贴一下我的,希望多多指教我

import re,os,time,random,lxml,sys
from lxml import etree
import requests
from bs4 import BeautifulSoup
from requests.adapters import HTTPAdapter
from concurrent.futures import ThreadPoolExecutor,wait,ALL_COMPLETED
os.system('title 优美图吧整站爬虫程序 @小伍的游乐场-5yang.cc')#设置窗口标题
#coding:utf-8
result = []
urls = []
down_path = '优美图吧'
if not os.path.exists(down_path):
    os.makedirs(down_path)

def getpage(url):
    headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36'}
    s = requests.session()#加入会话保持系统
    s.mount('http://', HTTPAdapter(max_retries=10))#http和https都为最大重试10次
    s.mount('https://', HTTPAdapter(max_retries=10))
    x = 0
    while x < 10:
        try:
            r = s.get(url,headers=headers,timeout = (20,20))
            if r.status_code == 200:
                return r.text
                print('该地址已经Return')
        except requests.exceptions.RequestException as e:
            print(e)
            x += 1
            print('出错重试!')

def lastpage(content,url):#获取lastpage
    zhengze = re.compile('page-numbers".*?"最后页">(.*?)</a>',re.S)
    picurl = re.findall(zhengze,content)#取得每个页面的最大page,例如某图集最大42页
    if len(picurl) == 0:#判断列表是否为空
#        print('该页面为空,不存在最大页面: ',url)
        return 0
    else:   
        lastpage = picurl[0]#最大page是列表,取出来使用
        #print(lastpage)
        return lastpage

def pingjie(cc):
    pingjie1 = re.sub('.html','',url)#将.html替换为空
    pinjie2 = pingjie1+'_'+ str(x) +'.html'
    urls.append(pinjie2)


def down_pic(content):
    headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36'}
    picnamezz = re.compile('点击图片.*?alt="(.*?)" width',re.S)
    picname = re.findall(picnamezz,content)
    #print('该图片名称为:',picname[0])

    jpgnow = re.compile('点击图片查看.*?<img src="(.*?)" alt=".*? width',re.S)#正则中添加变量的方式
    #print(jpgnow)
    jpgdown = re.findall(jpgnow,content)#图片绝对地址
    #print('图片绝对地址为:',jpgdown[0])
   
    html = etree.HTML(content)
    filename = html.xpath('//*[@id="body-header-top"]/div[2]/div/div/div[2]/h1/text()')
    #print('该图集名称为:',filename[0])
    s = requests.session()#加入会话保持系统
    s.mount('http://', HTTPAdapter(max_retries=3))#http和https都为最大重试3次
    s.mount('https://', HTTPAdapter(max_retries=3))
    try:
        jpgget = s.get(jpgdown[0],headers=headers,timeout = (30,30))#这里的timeout分别是链接时间和读取时间,超时自动放弃
    except requests.exceptions.RequestException as e:#必须加入except,否则程序爆出的错误让你无法定位,之前没加我的程序报我语法错误,且错误在pagenum()
        print(e)
        print(time.strftime('%Y-%m-%d %H:%M:%S'))
    pass

    down_path1 = f'优美图吧/{filename[0]}'
    if not os.path.exists(f'优美图吧/{filename[0]}'):
        os.makedirs(f'优美图吧/{filename[0]}')
    try:
        #print(jpgdown) #打印图片绝对网址
        with open(f'优美图吧/{filename[0]}/{picname[0]}.jpg','wb') as f:
            f.write(jpgget.content)
            print(f'已完成{picname[0]}的下载')
    except:
        print('该图片下载超时,自动跳过...')




if __name__ == "__main__":

    url = 'https://www.umtuba.com/wp-admin/admin-ajax.php'

    headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36', 'X-Requested-With': 'XMLHttpRequest'}

    data = {'action': 'postlist_newajax', 'id': '0', 'type': 'index'}

    num = int(input('请问您要下载多少页 :'))
    print('时间较长,请耐心等待.')
    print('时间较长,请耐心等待..')
    print('时间较长,请耐心等待...')
    print('时间较长,请耐心等待....')
    print('时间较长,请耐心等待.....')
    print('时间较长,请耐心等待......')
    for item in range(num):
        data['paged'] = item
        r = requests.post(url, headers=headers, data=data)
        j_data = r.json()
    #print(j_data)
        result.extend(re.findall(r'<a href="(.*?)"', str(j_data)))
#print(result)

    for url in result:
        content = getpage(url)
        cc = lastpage(content,url)
        for x in range(1,int(cc)+1):
            pingjie(cc)
    print(urls)
    print('时间较长,请耐心等待.')
    print('时间较长,请耐心等待..')
    print('时间较长,请耐心等待...')
    print('时间较长,请耐心等待....')
    print('时间较长,请耐心等待.....')
    print('时间较长,请耐心等待......')



#    for url in urls:
#        down_pic(getpage(url))
    ex = ThreadPoolExecutor(max_workers = 20)
    future = [ex.submit(down_pic,getpage(url)) for url in urls]
    wait(future,return_when=ALL_COMPLETED)

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-6-18 14:48:54 | 显示全部楼层
suchocolate 发表于 2020-6-18 12:54
正则比较麻烦,还是建议用xpath,给你写了一个整个网站的爬虫,不过这个网站慢,建议数字改小:

还有一个小小的疑问,我尝试了接收类型为text,
j_data你的接收类型是json
可是我怎么知道我需要接收什么类型呢?难道每一次我都接收来尝试一下吗?
您是如何知道接收数据类型为json的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-6-18 19:38:57 | 显示全部楼层
nanrenne 发表于 2020-6-18 14:48
还有一个小小的疑问,我尝试了接收类型为text,
j_data你的接收类型是json
可是我怎么知道我需要接收什 ...

还是【浏览器f12】-【网络】,登陆网址https://www.umtuba.com/wp-admin/admin-ajax.php一看返回参数就是json,所以都是json。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-6-18 23:19:40 | 显示全部楼层
suchocolate 发表于 2020-6-18 19:38
还是【浏览器f12】-【网络】,登陆网址https://www.umtuba.com/wp-admin/admin-ajax.php一看返回参数就是 ...

打开主页 点击Ajax加载更多,Network ---Respon里面是
{"success":"ok","msg":
这样的大括号就证明是json吗
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-6-19 08:31:40 | 显示全部楼层
本帖最后由 suchocolate 于 2020-6-19 08:33 编辑
nanrenne 发表于 2020-6-18 23:19
打开主页 点击Ajax加载更多,Network ---Respon里面是
{"success":"ok","msg":
这样的大括号就证明是jso ...

一般是的,浏览器应该会提示这是个json数据。
我这里已经登录不上这个网站了,给你截个别的图网站的图例:
8.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-6-19 11:31:04 | 显示全部楼层
suchocolate 发表于 2020-6-19 08:31
一般是的,浏览器应该会提示这是个json数据。
我这里已经登录不上这个网站了,给你截个别的图网站的图例 ...

额 怪不得,我这没。我用的chrome
<a href="https://sm.ms/image/XI7L1B2Pe6qvFog" target="_blank"><img src="https://i.loli.net/2020/06/19/XI7L1B2Pe6qvFog.jpg" ></a>
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-6-19 11:36:14 | 显示全部楼层
suchocolate 发表于 2020-6-19 08:31
一般是的,浏览器应该会提示这是个json数据。
我这里已经登录不上这个网站了,给你截个别的图网站的图例 ...

额,我的chrome或者windows自带浏览器里面写的类型都是XHR,但是你的是触发,你多了一个类型写的是JSON
而那个站点在windows自带浏览器写的类型是text/html
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-20 13:20

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表