ajax抓取网页内容(AJAX(AsynchronousJavaScriptandXML)的思路想法想法AJAX先简单 )

优采云 发布时间: 2021-10-20 15:01

  ajax抓取网页内容(AJAX(AsynchronousJavaScriptandXML)的思路想法想法AJAX先简单

)

  想法 AJAX

  首先,让我们简单地了解一下什么是 AJAX。个人建议,如果你从来没有听说过下面提到的术语或者只是简单地使用过它们,那么你最好回去把每一项都填好,虽然这是一个写爬虫的好工具。这不是很有帮助,但对您深入了解计算机主题非常有帮助。重要的是要知道,语言和框架都有自己的目的。了解了这些,学起来就会相对容易一些。

  AJAX(Asynchronous JavaScript and XML),直译就是异步 JavaScript 和 XML。其实这个名字有点误导:据我所知,AJAX 至少还支持 json 文件,这可能是在这项技术发明时以 JavaScript 和 XML 命名的。这里的异步是指异步加载或异步数据交换。它是指在网页初始加载后,使用 XMLHttpRequst 或其他 fetch API 再次发送请求,从服务器获取并解析数据,然后将这部分数据添加到某些页面上,在此city,访问的 URL 从未改变。

  AJAX本质上是一个框架,通过它JavaScript可以达到部分更新网页的效果。这节省了 Internet 中的传输带宽。JavaScript 是一种浏览器脚本语言。它可以在不访问服务器的情况下修改客户端。例如,某些网站 有很多选项。当您选择其中之一时,会出现更多子选项。这实际上是由 Javascript 完成的。在您单击提交之前,浏览器不会与服务器交互。. AJAX 框架中使用的只是 JavaScript 众*敏*感*词*中的一小部分。

  今日头条

  嗯……其实我今天也不喜欢今日头条。我推送的内容越来越像UC今日头条了。如果你在头条页面搜索关键词古镇,你会得到多个文章,如果你把滑块拉到最底部,你会发现浏览器会自动加载更多文章,这是AJAX的一种体现。

  但是,无论是什么技术或框架,只要还在使用HTTP协议,就无法运行GET/POST及其响应。我们要做的就是找到这个关键的 GET 请求。

  你使用 AJAX

  判断一个网站是否使用AJAX可以从以下几点来看:

  综上所述,其实很容易看出。

  分析搜索页面

  

  toutiao-index页面分析.jpg

  过滤图中位置1的XHR标签,你会在位置2看到它的消息。第一次访问只有一个。随着进度条下拉,新的请求会不断出现。分析这四个消息,你可以在它的请求头中找到参数列表。我们只需要修改参数值。其他参数也可以修改。关键字是您搜索的 关键词。

  Requests URLs(只有offset变化了):

https://www.toutiao.com/search_content/?

offset=0&format=json&keyword=%E5%A1%9E%E5%B0%94%E8%BE%BE%E4%BC%A0%E8%AF%B4&autoload=true&count=20&cur_tab=1&from=search_tab

https://www.toutiao.com/search_content/?

offset=20&format=json&keyword=%E5%A1%9E%E5%B0%94%E8%BE%BE%E4%BC%A0%E8%AF%B4&autoload=true&count=20&cur_tab=1&from=search_tab

https://www.toutiao.com/search_content/?

offset=40&format=json&keyword=%E5%A1%9E%E5%B0%94%E8%BE%BE%E4%BC%A0%E8%AF%B4&autoload=true&count=20&cur_tab=1&from=search_tab

......

  这样,我们就有了访问的链接。随着offset=0, 20, 40, 60...的增加,每次请求都会返回上图3位置的json结构,收录不超过20条记录。如果json结构中的数据项为空,则表示没有结果,表示爬虫结束。有时候搜索结果很多,你也可以设置一个上限,比如最多爬到前50个搜索结果。

  

  今日头条-两种类型.jpg

  仔细看,会出现两种搜索结果,一种是文字+图片的结构,收录图片和文字;另一个是相册的结构,它会收录几张照片。这两个结果可以根据json结构体中的has_gallery和has_image字段来区分。

  我为每个结果对应的URL选择了article_url字段的值,但是这里其实有问题。在后续的爬取过程中,发现这个字段的值并不是所有的标题文章,有的是文章的源地址,估计是今日头条从网上爬取并添加的结果它自己的结果,通常出现在前几个。这种情况下,后面写的对应爬虫代码就不适用了,谁知道文章的源地址用的是什么结构。不过考虑到这样的情况并不多,我就简单的过滤一下。反正爬几页也不是问题。

  如果你有强迫症,我考虑的一种方法是使用sourcs_url字段的内容,但是这个地址会被重定向,所以需要调整get请求:

  https://www.toutiao.com/group/6544161999004107271/

Redirect to:

https://www.toutiao.com/a6544161999004107271/

  带画廊的页面

  

  今日头条-with atlas.jpg

  图片是这种页面中的图集。我们需要找出这12张图片的地址。因为已经确定要使用AJAX,所以这里要查一下它的网页源码,然后可以找到:

  

  toutiao-with atlas-js.jpg

  内容有时略有不同,但很容易找到。然后用正则表达式过滤出你想要的图片地址。这里有个技巧,这部分源码正好是json格式,可以过滤掉整个{},加载到字典中方便查阅。

  没有图库的页面

  没有图集的页面是文字+图片模式,但是标题的页面也是动态加载的。一开始以为是静态页面,看了源码才知道。

  

  今日头条-无图集-js.jpg

  也很容易找到图片的地址,还是用正则表达式过滤掉。

  代码结构自建URL,调整偏移量和关键字检索索引页,分析json.get('data')的结构,区分两种类型的页面,将提取的URL放入各自的列表中。两个解析函数用于解析两个页面,并将提取的图片地址写入文件。

  几个小问题:

  金日头条.py

  对于configure.py,请参考我的书:爬取尴尬百科的内容和图片并展示出来。

<p>import requests

import json

import time

import re

from random import choice

import configure

url = "https://www.toutiao.com/search_content/?"

header = {'user-agent': choice(configure.FakeUserAgents)}

keyword = '塞尔达传说'

has_gallery_lists = []

no_gallery_lists = []

def SearchPageParser(offset = 0):

payload = {

'offset':offset,

'format':'json',

'keyword':keyword,

'autoload':'true',

'count':30,

'cur_tab':1,

'from':'search_tab'

}

count = 0

try:

response = requests.get(url, headers=header, params=payload)

content = None

print ("Parser " + response.url)

if response.status_code == requests.codes.ok:

content = response.text

data = json.loads(content)

if not data:

return

for article in data.get('data'):

if True == article.get('has_gallery') and True == article.get('has_image'):

has_gallery_lists.append(article.get('article_url'))

count += 1

if False == article.get('has_gallery') and True == article.get('has_image'):

no_gallery_lists.append(article.get('article_url'))

count += 1

return count

except Exception as e:

print (e)

return

def SaveImage(imageURL):

# 这里就不下载了,只是把单纯写入文件

print (imageURL)

with open('toutiao.txt', 'a') as file:

file.write(imageURL + '\n')

def HasGalleryParser():

if 0 == len(has_gallery_lists):

return

# 这里写的时候注意(, ), ", ., 都是要转义的。

pattern = re.compile('gallery: JSON\.parse\("(.*?)max_img', re.S)

while has_gallery_lists:

this = has_gallery_lists.pop()

try:

response = requests.get(this, headers=header)

content = None

if response.status_code == requests.codes.ok:

content = response.text

data = pattern.findall(content)

if data:

data = data[0][:-4].replace('\\','') + ']}'

img_urls = json.loads(data).get('sub_images')

for img_url in img_urls:

SaveImage(img_url.get('url'))

else:

print ("BadPageURL[GalleryParser, {0:s}]".format(this))

except Exception as e:

print (e)

return

time.sleep(0.25)

def NoGalleryParser():

if 0 == len(no_gallery_lists):

return

while no_gallery_lists:

this = no_gallery_lists.pop()

pattern = re.compile('

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线