抓取ajax动态网页java(大多数网页数据都是通过动态渲染加载的,即常说的Ajax方式 )

优采云 发布时间: 2021-09-29 20:19

  抓取ajax动态网页java(大多数网页数据都是通过动态渲染加载的,即常说的Ajax方式

)

  目前的网页数据大部分是通过动态渲染加载的,也就是通常所说的Ajax方式。在这种类型的网站 爬取数据中通常是没有网页加载数据的。一般是找到动态加载页面然后获取数据,本文分析今日头条网站,搜索关键词获取搜索页面的图片和标题,最后通过简单的多线程保存到本地下载。

  1:打开今日头条主页,网址:今日头条主页

  

  页面右上角有一个搜索框,搜索关键词加载关键词信息。

  2:分析页面

  点击搜索后,页面重新加载并返回关键字信息界面。此页面未找到具体内容信息。由此可以判断它是一个Ajax加载页面。我们可以通过网络上的XHR查看加载信息。

  

  这里可以看到加载信息的url,也可以看到下面的请求头信息。

  我们在响应中观察返回网页的源代码,可以发现所有的数据都在这里。

  

  页面信息的数据中是具体的信息,如标题、图片列表等,我们可以通过这里获取信息来获取数据。

  3:多页面数据分析

  当页面向下滑动到最后时,会自动加载新的一页数据。这里我们观察后续链接的参数。我们可以发现唯一改变的参数是offset。第一次请求时偏移量为0,第二次请求时偏移值是20,第三次是40,第四次是60,所以我们可以找到规则,这个偏移值就是反向页偏移,然后我们可以推断count参数就是一次获取的数据个数,所以我们可以使用offset参数来控制数据分页。这样我们就可以通过接口批量获取数据,然后解析数据下载图片。

  其实通过传入URL关键词,还可以进一步实现关键词下载头条图片。

  4:程序实现

  只下载第一页

  import requests

from urllib.parse import urlencode #用 urlencode() 方法构造请求的 GET 参数

import os

from hashlib import md5

headers = {

'Host': 'www.toutiao.com',

'Referer': 'https://www.toutiao.com/search/?keyword=香港',

'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36',

'X-Requested-With': 'XMLHttpRequest',

'Cookie': 'tt_webid=6704808321848215043; WEATHER_CITY=武汉; UM_distinctid=16b77e85ac24d7-006d237c790a88-4a5568-1fa400-16b77e85ac344b; CNZZDATA1259612802=1104480020-1561079689-%7C1561079689; __tasessionId=n39mykl9q1561084844772; tt_webid=6704808321848215043; csrftoken=dcd1d465bc7441c32e8f77a18e4dcb62; s_v_web_id=bfc941bbb6430551a71c9f370afd2c71TE: Trailers'

}

def get_page(offset):

params={

'aid':24,

'app_name':'web_search',

'format':'json',

'keyword':'香港',

'autoload':'true',

'count':20,

'en_qc':1,

'from':'search_tab',

'pd':'synthesis',

'timestamp':'1561085020266',

'offset':offset

}

url='https://www.toutiao.com/api/search/content/?'+urlencode(params)

response=requests.get(url,headers=headers)

if response.status_code==200:

return response.json()

return None

def get_image(page):

if page.get('data'):

for item in page.get('data'):

title=item.get('title',None)

image_list=item.get('image_list',[])

if title:

yield { #*敏*感*词*,返回标题和图像url列表

'title':title,

'image_list':image_list

}

def save_image(item):

if not os.path.exists('E:\\toutiao\\'+item.get('title')): #如果不存在就创建

os.mkdir('E:\\toutiao\\'+item.get('title'))

for img in item.get('image_list'):

print(img.get('url'))

response=requests.get(img.get('url'))

if response.status_code==200:

file_path='E:\\toutiao\\{0}\\{1}.{2}'.format(item.get('title'),

md5(response.content).hexdigest(),

'jpg') #使用MD5编码,防止命名重复

if not os.path.exists(file_path):

with open(file_path,'wb') as f:

f.write(response.content) #下载二进制数据

else:

print('已经下载了')

else:

print(response.reason)

if __name__ == '__main__':

x=get_page(0)

for y in get_image(x):

save_image(y)

  多线程下载多个页面

  在上述程序的基础上增加一个新的main函数main

  from multiprocessing.pool import Pool

def main(offset):

json = get_page(offset)

for item in get_images(json):

print(item)

save_image(item)

GROUP_START = 1 #其实页面

GROUP_END = 20 #终止页面

if __name__ == '__main__':

pool = Pool() #创建多线程

groups = ([x * 20 for x in range(GROUP_START, GROUP_END + 1)]) #构造多个参数

pool.map(main, groups) #传入多个参数,多个函数同时运行

pool.close()

pool.join()

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线