>  기사  >  백엔드 개발  >  JS로 렌더링된 웹 페이지에 대한 Ajax 요청을 분석하는 방법

JS로 렌더링된 웹 페이지에 대한 Ajax 요청을 분석하는 방법

爱喝马黛茶的安东尼
爱喝马黛茶的安东尼앞으로
2019-06-05 18:03:023661검색

python을 사용하여 크롤링할 때 일부 웹페이지에서 직접 요청하여 얻은 HTML 코드에 필요한 데이터, 즉 볼 때 포함되지 않은 데이터가 포함되어 있을 수 있습니다. 브라우저에서 콘텐츠로 이동합니다.

이 정보는 Ajax를 통해 로드되고 js 렌더링을 통해 생성되기 때문입니다. 지금은 이 웹페이지의 요청을 분석해야 합니다.

이전 글에서는 쿠키와 모의 로그인 동작 과정에 대해 설명드렸습니다. 오늘은 웹페이지의 Ajax 요청을 분석하는 방법을 알려드리겠습니다.

JS로 렌더링된 웹 페이지에 대한 Ajax 요청을 분석하는 방법

Ajax란 무엇인가요

AJAX는 "Asynchronous Javascript And XML"과 XML을 의미합니다. )은 대화형 웹 애플리케이션을 만들기 위한 웹 개발 기술을 말한다.
AJAX = 비동기 JavaScript 및 XML(표준 범용 마크업 언어의 하위 집합).
AJAX는 빠르고 동적인 웹페이지를 만드는 데 사용되는 기술입니다.
AJAX는 전체 웹페이지를 다시 로드하지 않고도 웹페이지의 일부를 업데이트할 수 있는 기술입니다.

간단히 말하면 웹페이지가 로드된다는 뜻입니다. 브라우저 주소 표시줄의 URL이 변경되지 않았습니다. ajax여야 하는 javascript에 의해 비동기적으로 로드되는 웹페이지입니다. AJAX는 일반적으로 XMLHttpRequest 객체 인터페이스를 통해 요청을 보내고 XMLHttpRequest는 일반적으로 XHR로 축약됩니다.

Analyze Guoker 웹사이트

우리의 타겟 웹사이트는 Guoker를 사용하여 분석됩니다.

이 웹페이지에는 페이지 넘김 버튼이 없는 것을 볼 수 있으며, 요청을 계속해서 당기면 웹페이지가 자동으로 더 많은 콘텐츠를 로드합니다. 그러나 웹페이지 URL을 관찰하면 웹페이지 로딩 요청에 따라 변경되지 않는다는 것을 알 수 있습니다. 그리고 이 URL을 직접 요청하면 당연히 첫 번째 페이지의 html 콘텐츠만 얻을 수 있습니다.

JS로 렌더링된 웹 페이지에 대한 Ajax 요청을 분석하는 방법

그렇다면 모든 페이지의 데이터를 어떻게 얻을 수 있을까요?

Chrome에서 개발자 도구(F12)를 엽니다. Network를 클릭하고 XHR 탭을 클릭합니다. 그런 다음 웹페이지를 새로 고치고 요청을 풀다운합니다. 이때 XHR 태그를 볼 수 있으며 웹페이지가 로드될 때마다 요청이 팝업됩니다.

첫 번째 요청을 클릭하면 해당 매개변수를 볼 수 있습니다.

retrieve_type:by_subject
limit:20
offset:18
-:1500265766286

두 번째 요청을 클릭하면 매개변수가 다음과 같습니다.

retrieve_type:by_subject
limit:20
offset:38
-:1500265766287

Limit 매개변수는 웹페이지의 각 페이지에 로드되는 기사 수의 제한이고, 오프셋은 페이지 수입니다. 아래를 살펴보면 각 요청의 오프셋 매개변수가 20씩 증가한다는 것을 알 수 있습니다.

그런 다음 각 요청의 응답 내용을 살펴봅니다. 이는 형식의 데이터입니다. 결과 버튼을 클릭하면 20개 기사의 데이터 정보를 볼 수 있습니다. 이런 식으로 우리는 필요한 정보의 위치를 ​​성공적으로 찾았습니다. 요청 헤더에 json 데이터가 저장된 URL 주소를 볼 수 있습니다. http://www.guokr.com/apis/minisite/article.json?retrieve_type=by_subject&limit=20&offset=18

JS로 렌더링된 웹 페이지에 대한 Ajax 요청을 분석하는 방법# 🎜🎜#

크롤링 프로세스

Ajax 요청을 분석하여 각 페이지의 기사 URL 정보를 구문 분석하고 필요한 데이터를 얻습니다. 데이터는 데이터베이스에 저장되며, 많은 수의 데이터를 캡처하기 위해 여러 프로세스가 활성화됩니다.

Start

우리 도구는 여전히 요청 요청과 BeautifulSoup 구문 분석을 사용합니다.

우선, 모든 페이지의 정보를 얻기 위해 Ajax 요청을 분석해야 합니다. 위의 웹 페이지 분석을 통해 Ajax가 로드한 json 데이터의 URL 주소를 얻을 수 있습니다.

http:/ /www.guokr.com/apis/minisite/article.json?retrieve_type=by_subject&limit=20&offset=18

우리는 이것을 구성해야 합니다 URL.

# 导入可能要用到的模块
import requests
from urllib.parse import urlencode
from requests.exceptions import ConnectionError
 
# 获得索引页的信息
def get_index(offset):
    base_url = 'http://www.guokr.com/apis/minisite/article.json?'
    data = {
        'retrieve_type': "by_subject",
        'limit': "20",
        'offset': offset
    }
    params = urlencode(data)
    url = base_url + params
 
    try:
        resp = requests.get(url)
        if resp.status_code == 200:
            return resp.text
        return None
    except ConnectionError:
        print('Error.')
        return None

위 분석 페이지에서 얻은 요청 매개변수를 사전 데이터로 구성한 다음 이 URL을 수동으로 구성할 수 있지만 urllib 라이브러리에서 제공한 a 인코딩 방법을 직접 사용하여 완전한 URL을 구성할 수 있습니다. 그런 다음 페이지 콘텐츠를 요청하는 표준 요청이 있습니다.

import json
 
# 解析json,获得文章url
def parse_json(text):
    try:
        result = json.loads(text)
        if result:
            for i in result.get('result'):
                # print(i.get('url'))
                yield i.get('url')
    except:
        pass

josn.loads 메소드를 사용하여 json을 구문 분석하고 이를 json 객체로 변환합니다. 그런 다음 사전 작업을 통해 기사의 URL 주소를 직접 얻습니다. 여기서는 Yield가 사용되며 각 요청은 메모리 소비를 줄이기 위해 URL을 반환합니다. 나중에 가져왔을 때 json 구문 분석 오류가 발생했기 때문에 여기에서 필터링했습니다.

여기서 인쇄를 시도하여 성공적으로 실행되는지 확인할 수 있습니다.

既然获得了文章的url,那么对于获得文章的数据就显得很简单了。这里不在进行详细的叙述。我们的目标是获得文章的标题,作者和内容。
由于有的文章里面包含一些图片,我们直接过滤掉文章内容里的图片就好了。

from bs4 import BeautifulSoup
 
# 解析文章页
def parse_page(text):
    try:
        soup = BeautifulSoup(text, 'lxml')
        content = soup.find('div', class_="content")
        title = content.find('h1', id="articleTitle").get_text()
        author = 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')]
        article = '\n'.join(all_p)
        # print(title,'\n',author,'\n',article)
        data = {
            'title': title,
            'author': author,
            'article': article
        }
        return data
    except:
        pass

   

这里在进行多进程抓取的时候,BeautifulSoup也会出现一个错误,依然直接过滤。我们把得到的数据保存为字典的形式,方便保存数据库。

接下来就是保存数据库的操作了,这里我们使用Mongodb进行数据的存储。

import pymongo
from config import *
 
client = pymongo.MongoClient(MONGO_URL, 27017)
db = client[MONGO_DB]
 
def save_database(data):
    if db[MONGO_TABLE].insert(data):
        print('Save to Database successful', data)
        return True
    return False

我们把数据库的名字,和表名保存到config配置文件中,在把配置信息导入文件,这样会方便代码的管理。

最后呢,由于果壳网数据还是比较多的,如果想要大量的抓取,我们可以使用多进程。

from multiprocessing import Pool
 
# 定义一个主函数
def main(offset):
    text = get_index(offset)
    all_url = parse_json(text)
    for url in all_url:
        resp = get_page(url)
        data = parse_page(resp)
        if data:
            save_database(data)
 
if __name__ == '__main__':
    pool = Pool()
    offsets = ([0] + [i*20+18 for i in range(500)])
    pool.map(main, offsets)
    pool.close()
    pool.join()

   

函数的参数offset就是页数了。经过我的观察,果壳网最后一页页码是 12758,有 637 页。这里我们就抓取 500 页。进程池的map方法和Python内置的map方法使用类似。

JS로 렌더링된 웹 페이지에 대한 Ajax 요청을 분석하는 방법

好了,对于一些使用Ajax加载的网页,我们就可以这么抓取了。

위 내용은 JS로 렌더링된 웹 페이지에 대한 Ajax 요청을 분석하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 csdn.net에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제