ajax抓取网页内容(AJAX(AsynchronousJavaScriptandXML)的思路想法想法AJAX先简单 )
优采云 发布时间: 2021-10-20 15:01ajax抓取网页内容(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('