ajax抓取网页内容(什么是Cookie及模拟登录的操作流程:Ajax加载)
优采云 发布时间: 2022-04-13 07:14ajax抓取网页内容(什么是Cookie及模拟登录的操作流程:Ajax加载)
我们在使用python进行爬取的时候,可能遇到过一些网页直接请求的html代码,并没有我们需要的数据,也就是我们在浏览器中看到的。
这是因为信息是通过 Ajax 加载并通过 js 渲染生成的。这时,我们需要分析这个网页的请求。
上一篇给大家讲解了什么是cookie以及模拟登录的操作流程。今天给大家带来如何分析网页的ajax请求。
什么是阿贾克斯
AJAX 是“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),它指的是一种用于创建交互式 Web 应用程序的 Web 开发技术。
AJAX = 异步 JavaScript 和 XML(标准通用标记语言的子集)。
AJAX 是一种用于创建快速、动态网页的技术。
AJAX 是一种无需重新加载整个网页即可更新部分网页的技术。
简单地说,就是加载了网页。浏览器地址栏中的 URL 没有改变。是javascript异步加载的网页,应该是ajax。AJAX一般通过XMLHttpRequest对象接口发送请求,一般简称为XHR。
分析简而言之网站点
我们的目标网站是用壳网来分析。
我们可以看到这个网页没有翻页按钮,当我们不断拉下请求时,网页会自动为我们加载更多内容。但是,当我们查看网页 url 时,它并没有随着页面加载请求而改变。而当我们直接请求这个url时,显然只能获取到第一页的html内容。
那么我们如何获取所有页面的数据呢?
我们在Chrome中打开开发者工具(F12)。我们点击Network,点击XHR选项卡。然后我们刷新页面并拉下请求。这时候我们可以看到XHR选项卡,每次页面加载会弹出一个请求。
我们点击第一个请求,可以看到他的参数:retrieve_type:by_subject
限制:20
偏移量:18
-:86
点击第二个请求后,参数如下:retrieve_type:by_subject
限制:20
偏移量:38
-:87
limit参数是网页每页被限制加载的文章个数,offset是页数。然后往下看,我们会发现每次请求的offset参数都会增加20。
然后我们查看每个请求的响应内容,这是一个格式化的数据。我们点击结果按钮,可以看到20条文章的数据信息。这样我们就成功找到了我们需要的信息的位置,在请求头中可以看到json数据存放的url地址。
爬取过程
分析Ajax请求,获取每个页面的文章url信息;解析每个文章,获取需要的数据;将获取的数据保存在数据库中;打开多个进程,爬了很多。
开始
我们的工具仍然使用 BeautifulSoup 解析的请求。
我们需要构造这个 URL。# 导入可能用到的模块
导入请求
从 urllib.parse 导入 urlencode
从 requests.exceptions 导入 ConnectionError
# 获取索引页面的信息
def get_index(偏移量):
base_url = '#39;
数据 = {
'retrieve_type': "by_subject",
'限制':“20”,
“偏移量”:偏移量
}
参数 = urlencode(数据)
url = base_url + 参数
尝试:
resp = requests.get(url)
如果 resp.status_code == 200:
返回对应文本
返回无
除了连接错误:
打印('错误。')
返回无
我们将从上面分析页面得到的请求参数构造成字典数据,然后我们可以手动构造url,但是urllib库已经为我们提供了编码方式,我们可以直接使用它来构造完整的url。然后是请求页面内容的标准请求。导入json
# 解析json,得到文章url
def parse_json(文本):
尝试:
结果 = json.loads(文本)
如果结果:
对于我在 result.get('result') 中:
# 打印(i.get('url'))
产量 i.get('url')
除了:
经过
我们使用 josn.loads 方法解析 json 并将其转换为 json 对象。然后直接通过字典的操作,得到文章的url地址。这里使用yield为每个请求返回一个url,以减少内存消耗。由于后面爬的时候会弹出一个json解析错误,这里直接过滤就好了。
这里我们可以尝试打印看看是否运行成功。
既然获取了文章的url,那么获取文章的数据就很简单了。此处不作详细说明。目标是获取 文章 的标题、作者和内容。
由于有的文章收录了一些图片,所以我们可以过滤掉文章内容中的图片。从 bs4 导入 BeautifulSoup
# 解析 文章 页面
def parse_page(文本):
尝试:
汤= BeautifulSoup(文本,'lxml')
content = soup.find('div', class_="content")
标题 = content.find('h1',).get_text()
作者 = content.find('div', class_="content-th-info").find('a').get_text()
article_content = content.find('div', class_="document").find_all('p')
all_p = [i.get_text() for i in article_content if not i.find('img') and not i.find('a')]
文章 = '\n'.join(all_p)
# 打印(标题,'\n',作者,'\n',文章)
数据 = {
'标题':标题,
“作者”:作者,
“文章”:文章
}
返回数据
除了:
经过
这里,在进行多进程爬取的时候,BeautifulSoup也会报错,还是直接过滤。我们将得到的数据以字典的形式保存,方便保存数据库。
下一步是保存数据库的操作。这里我们使用MongoDB进行数据存储。导入pymongo
从配置导入 *
客户端 = pymongo.MongoClient(MONGO_URL, 27017)
db = 客户[MONGO_DB]
def save_database(数据):
如果 db[MONGO_TABLE].insert(data):
print('保存到数据库成功', data)
返回真
返回假
我们将数据库名和表名保存在config配置文件中,并将配置信息导入到文件中,这样会方便代码的管理。
最后,由于诺虎网的数据还是很多的,如果我们想抓取很多数据,可以使用多进程。从多处理导入池
# 定义一个主函数
定义主(偏移):
文本 = get_index(偏移量)
all_url = parse_json(文本)
对于 all_url 中的 url:
resp = get_page(url)
数据 = parse_page(resp)
如果数据:
保存数据库(数据)
如果 __name__ == '__main__':
池 = 池()
偏移量 = ([0] + [i*20+18 for i in range(500)])
pool.map(主要,偏移量)
池.close()
pool.join()
该函数的参数偏移量是页数。经过我的观察,国科网的最后一个页码是12758,有637页。在这里,我们抓取了 500 个页面。进程池的map方法类似于Python内置的map方法。
那么对于一些使用Ajax加载的网页,我们可以这样爬取。