ajax抓取网页内容(请求网页源数据的代码:接下来应该解析网页中的数据 )

优采云 发布时间: 2022-01-02 08:02

  ajax抓取网页内容(请求网页源数据的代码:接下来应该解析网页中的数据

)

  一般我们从网页爬取内容的时候,都是html代码,内容已经写好了,直接从页面中获取自己想要的信息,但是有些网页是通过ajax获取数据,获取ajax的数据以json格式接收,然后显示在页面上。也就是说,当我们打开一个页面时,第一个请求是他的html,然后通过html中的ajax获取后端数据,数据以json格式显示在Page中。最近的头条新闻就是这种情况。我们来看看。

  我们打开链接:%E8%A1%97%E6%8B%8D,发现下图中的链接和我们粘贴复制的地址不一样,说明最终请求的数据通过了ajax请求,并且数据格式发生了变化。我们检查了网页的源代码,发现页面上没有关于我们在标题中看到的内容的信息。

  

  我们使用开发者选项F12查看网页元素,发现请求头中的url和我们上面的连接不一样,增加了很多信息

  

  我们查看了请求的参数,发现参数很多。这是实际通过ajax访问的数据连接。我们需要在下面的各个参数中加上+,才能看到真实的数据源。

  

  以下是请求网页源数据的代码:

  

  #请求网页具体信息的函数

def get_page_index(offset,keyword):

data={

'offset': offset,

'format': 'json',

'keyword': keyword,

'autoload': 'true',

'count': '20',

'cur_tab':3,

'from': 'search_tab'

}

url='https://www.toutiao.com/search_content/?'+urlencode(data)

try:

response = requests.get(url)

if response.status_code == 200:

return response.text

return None

except RequestException:

return None

  

  接下来要解析网页中的数据:我们通过上面的请求方法得到的是ajax请求返回的json数据。在这些数据中,我们需要一个指向每个标题的链接。以下是解析函数:

  def parse_page_index(html):

data = json.loads(html)#将获取的ajax请求转换为json类型的数据

if data and 'data' in data.keys():

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

yield item.get('article_url')#从json数据中获取名为artile_url的数据

  接下来我们需要根据上面得到的URL请求每个标题的内容:

  

  def get_page_datail(url):

headers = {

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

}

try:

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

if response.status_code == 200:

return response.text

return None

except RequestException:

print('出现错误')

return None

注意:这里我们添加了请求头,添加请求头的原因是有的网页防止python爬取数据,我们可以通过伪代理或者添加header的方式来避免。

  

  我们打开了标题中的一条新闻,查看了网页的源代码,发现看不到这条消息的数据。这些数据都收录在ajax请求返回的json数据中,我们需要从中提取数据。

  

  我们需要从网页中解析,代码如下:

  

  def pase_page_detail(html,url):

soup=BeautifulSoup(html,'lxml')#使用beautifulsoup解析库来解析网页

title = soup.select('title')[0].get_text()#直接可以通过标签名来获取头条的名称

print(title)

images_pattern = re.compile('BASE_DATA.galleryInfo.*?gallery: JSON.parse\("(.*?)"\),',re.S)#这里我们使用正则表达式获取我们想要图片的信息

result = re.search(images_pattern,html)

if not result is None:#有的网页中不含有符合正则表达式的内容,我们直接将之过滤

data=json.loads(result.group(1).replace('\\',''))#将\\转义替换为空字符,同时将图片的信息转为json格式

if data and 'sub_images'in data.keys():#判断数据不为空并且里面含有图片的信息

sub_images=data.get('sub_images')#从json数据中获取名为sub_images的内容

images=[item.get('url') for item in sub_images]#有的新闻中含有多张图片,我们将图片的链接存在数组中

for image in images:

get_save_image(image)#请求图片的链接

return{

'title':title,

'url':url,

'image':images

}#将我们得到的数据以数组格式返回,需要标题,url,还有图片链接

  

  接下来我们需要将这些数据存储到MongoDB数据库中,首先定义几个静态变量,并新建一个config.py python文件

  MONGO_URL='localhost'#数据库的ip就是localhost

MONGO_DB='toutiao'#存放的数据库名称

MONGO_TABLE='toutiao'#存放的表名称

  在写代码的python文件中定义数据库:

  client = pymongo.MongoClient(MONGO_URL,connect=False)

db = client[MONGO_DB]

  以下是MongoDB中存储的函数:

  def save_to_mongo(result):

if db[MONGO_TABLE].insert(result):

print('存储到数据库成功',result)

return True

return False

  我们也有把图片保存到本地的功能,这里我直接上传所有代码:

  

  import json

import os

import re

from hashlib import md5

from multiprocessing import Pool

from urllib.parse import urlencode

import pymongo

from config import *

client = pymongo.MongoClient(MONGO_URL,connect=False)

db = client[MONGO_DB]

from bs4 import BeautifulSoup

from requests.exceptions import RequestException

import requests

#请求网页具体信息的函数

def get_page_index(offset,keyword):

data={

'offset': offset,

'format': 'json',

'keyword': keyword,

'autoload': 'true',

'count': '20',

'cur_tab':3,

'from': 'search_tab'

}

url='https://www.toutiao.com/search_content/?'+urlencode(data)

try:

response = requests.get(url)

if response.status_code == 200:

return response.text

return None

except RequestException:

return None

def parse_page_index(html):

data = json.loads(html)#将获取的ajax请求转换为json类型的数据

if data and 'data' in data.keys():

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

yield item.get('article_url')#从json数据中获取名为artile_url的数据

def get_page_datail(url):

headers = {

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

}

try:

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

if response.status_code == 200:

return response.text

return None

except RequestException:

print('出现错误')

return None

def pase_page_detail(html,url):

soup=BeautifulSoup(html,'lxml')#使用beautifulsoup解析库来解析网页

title = soup.select('title')[0].get_text()#直接可以通过标签名来获取头条的名称

print(title)

images_pattern = re.compile('BASE_DATA.galleryInfo.*?gallery: JSON.parse\("(.*?)"\),',re.S)#这里我们使用正则表达式获取我们想要图片的信息

result = re.search(images_pattern,html)

if not result is None:#有的网页中不含有符合正则表达式的内容,我们直接将之过滤

data=json.loads(result.group(1).replace('\\',''))#将\\转义替换为空字符,同时将图片的信息转为json格式

if data and 'sub_images'in data.keys():#判断数据不为空并且里面含有图片的信息

sub_images=data.get('sub_images')#从json数据中获取名为sub_images的内容

images=[item.get('url') for item in sub_images]#有的新闻中含有多张图片,我们将图片的链接存在数组中

for image in images:

get_save_image(image)#请求图片的链接

return{

'title':title,

'url':url,

'image':images

}#将我们得到的数据以数组格式返回,需要标题,url,还有图片链接

def save_to_mongo(result):

if db[MONGO_TABLE].insert(result):

print('存储到数据库成功',result)

return True

return False

def get_save_image(url):

headers = {

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

}

try:

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

if response.status_code == 200:

save_image(response.content)

return None

except RequestException:

print('请求图片界面错误')

return None

def save_image(content):

file_path='{0}/{1}.{2}'.format(os.getcwd(),md5(content).hexdigest(),'jpg')

if not os._exists(file_path):

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

f.write(content)

f.close()

def main(offset):

html=get_page_index(offset,'街拍')

for url in parse_page_index(html):

if url:

html1=get_page_datail(url)

if html:

result=pase_page_detail(html1,url)

if not result is None:

save_to_mongo(result)

if __name__ == '__main__':

groups = [x*2 for x in range(GROUP_START,GROUP_END+1)]

pool = Pool()

pool.map(main,groups)

  

  以下是MongoDB中的信息:

  

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线