nanrenne 发表于 2020-6-17 13:53:08

求教此网站的Ajax该如何处理?

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

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

谢谢!

suchocolate 发表于 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)

nanrenne 发表于 2020-6-17 20:40:28

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

真棒的解答,很适合学习的答案.

nanrenne 发表于 2020-6-17 20:45:06

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

哎?获取到的每一条URL都重复了一次

nanrenne 发表于 2020-6-17 20:47:08

nanrenne 发表于 2020-6-17 20:45
哎?获取到的每一条URL都重复了一次

哦哦,确实 ,在源文件中就出现了2此

suchocolate 发表于 2020-6-17 21:02:06

nanrenne 发表于 2020-6-17 20:47
哦哦,确实 ,在源文件中就出现了2此

这个我没注意,你可以用set去重:result = set(result)
result = list(result)
print(result)

nanrenne 发表于 2020-6-17 21:53:07

suchocolate 发表于 2020-6-17 21:02
这个我没注意,你可以用set去重:

谢谢,之前我也这么用,后来发现他会乱序,改了一下正则,目前好啦.十分感谢

nanrenne 发表于 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)

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

以上的jpgnow的正则匹配就是不对,我第一次从正则内添加变量,可是这样匹配不到为什么呢

suchocolate 发表于 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/@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()')
      # print(picname)
      lastpagenum = html.xpath('//a[@title="最后页"]/text()')
      # print(lastpagenum)
      piclist = html.xpath('//img/@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)

nanrenne 发表于 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#最大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)

    jpgnow = re.compile('点击图片查看.*?<img src="(.*?)" alt=".*? width',re.S)#正则中添加变量的方式
    #print(jpgnow)
    jpgdown = re.findall(jpgnow,content)#图片绝对地址
    #print('图片绝对地址为:',jpgdown)
   
    html = etree.HTML(content)
    filename = html.xpath('//*[@id="body-header-top"]/div/div/div/div/h1/text()')
    #print('该图集名称为:',filename)
    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,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}'
    if not os.path.exists(f'优美图吧/{filename}'):
      os.makedirs(f'优美图吧/{filename}')
    try:
      #print(jpgdown) #打印图片绝对网址
      with open(f'优美图吧/{filename}/{picname}.jpg','wb') as f:
            f.write(jpgget.content)
            print(f'已完成{picname}的下载')
    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 =
    wait(future,return_when=ALL_COMPLETED)

nanrenne 发表于 2020-6-18 14:48:54

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

还有一个小小的疑问,我尝试了接收类型为text,
j_data你的接收类型是json
可是我怎么知道我需要接收什么类型呢?难道每一次我都接收来尝试一下吗?
您是如何知道接收数据类型为json的

suchocolate 发表于 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。

nanrenne 发表于 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吗

suchocolate 发表于 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数据。
我这里已经登录不上这个网站了,给你截个别的图网站的图例:

nanrenne 发表于 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>

nanrenne 发表于 2020-6-19 11:36:14

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

额,我的chrome或者windows自带浏览器里面写的类型都是XHR,但是你的是触发,你多了一个类型写的是JSON
而那个站点在windows自带浏览器写的类型是text/html
页: [1]
查看完整版本: 求教此网站的Ajax该如何处理?