
ajax抓取网页内容
ajax抓取网页内容(请求网页源数据的代码:接下来应该解析网页中的数据 )
网站优化 • 优采云 发表了文章 • 0 个评论 • 38 次浏览 • 2022-01-02 08:02
)
一般我们从网页爬取内容的时候,都是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中的信息:
查看全部
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中的信息:
ajax抓取网页内容(ScreamingFrogSEOSpiderforMac软件介绍(一)_)
网站优化 • 优采云 发表了文章 • 0 个评论 • 48 次浏览 • 2021-12-31 19:18
Screaming Frog SEO Spider for Mac 是一款专门用于抓取网址进行分析的网络爬虫开发工具。您可以使用本软件快速抓取网站中可能出现的断链和服务器错误,或者识别网站中临时和永久重定向的链接周期,也可以检查重复问题信息中心可能出现的URL、页面标题、描述、内容等。
Screaming Frog SEO Spider for Mac 软件介绍
Screaming Frog SEO Spider for Mac 是一款网站 爬虫,可让您爬取网站 的网址,获取关键元素、分析和审计技术以及现场搜索引擎优化。
Mac 版 Screaming Frog SEO Spider 的功能
1、找到失效链接
立即抓取 网站 并找到断开的链接 (404) 和服务器错误。批量导出错误和源网址进行修复或发送给开发者。
2、审核重定向
查找临时和永久重定向,识别重定向链和循环,或上传 URL 列表以在网站迁移期间进行审核。
3、分析页面标题和元数据
在抓取过程中分析页面标题和元描述,识别网站过长、缺失、缺失或重复的内容。
4、发现重复内容
使用 md5 算法检查和查找完全重复的 URL、部分重复的元素(例如页面标题、描述或标题)并查找低内容页面。
5、使用XPath提取数据
使用 CSS Path、XPath 或正则表达式从网页的 HTML 中采集任何数据。这可能包括社交元标签、其他标题、价格、SKU 或更多!
6、查看机器人和说明
查看被 robots.txt、元机器人或 X-Robots-Tag 指令(例如“noindex”或“nofollow”)以及规范和 rel="next" 和 rel="prev" 阻止的 URL。
7、生成 XML 站点地图
快速创建 XML 站点地图和图片 XML 站点地图,并通过 URL 进行高级配置,包括最后修改、优先级和更改频率。
8、与 Google Analytics 集成
连接到 Google Analytics API 并获取用于抓取功能的用户数据,例如会话或跳出率以及着陆页的转化、目标、交易和收入。
9、抓取 JavaScript网站
使用集成的 Chromium WRS 来渲染网页以抓取动态的、富含 JavaScript 的 网站 和框架,例如 Angular、React 和 Vue.js。
10、可视化网站架构
使用交互式爬虫和目录强制地图和树形地图站点来直观地评估内部链接和 URL 结构。
Screaming Frog SEO Spider for Mac 快速总结
错误 - 客户端错误,例如断开的链接和服务器错误(无响应、4XX、5XX)。
永久重定向、临时重定向(3XX 响应)和 JS 重定向。
被阻止的网址 - robots.txt 协议不允许查看和审查网址。
被阻止的资源 - 在演示模式下查看和审核被阻止的资源。
外部链接-所有外部链接及其状态代码。
协议 - URL 是安全 (HTTP) 还是不安全 (HTTP)。
URI 问题 - 非 ASCII 字符、下划线、大写字符、参数或长 URL。
重复页面-哈希/MD5校验和算法来检查完全重复的页面。
页面标题缺失、重复、超过65个字符、较短、像素宽度被截断、等于或大于h1。
元描述-缺失、重复、超过 156 个字符、短、截断或像素宽度多。
元关键字 - 主要供参考,因为它们未被 Google、Bing 或 Yahoo 使用。
文件大小-网址和图片的大小。
响应时间。
最后修改的标题。
页面(抓取)深度。
字数统计。
H1-缺失,重复,超过70个字符,不止一个。
H2-缺失,重复,超过70个字符,不止一个。
元机器人索引、无索引、follow、nofollow、noarchive、nosnippet、noodp、noydir等
元刷新——包括目标页面和时间延迟。 查看全部
ajax抓取网页内容(ScreamingFrogSEOSpiderforMac软件介绍(一)_)
Screaming Frog SEO Spider for Mac 是一款专门用于抓取网址进行分析的网络爬虫开发工具。您可以使用本软件快速抓取网站中可能出现的断链和服务器错误,或者识别网站中临时和永久重定向的链接周期,也可以检查重复问题信息中心可能出现的URL、页面标题、描述、内容等。
Screaming Frog SEO Spider for Mac 软件介绍
Screaming Frog SEO Spider for Mac 是一款网站 爬虫,可让您爬取网站 的网址,获取关键元素、分析和审计技术以及现场搜索引擎优化。
Mac 版 Screaming Frog SEO Spider 的功能
1、找到失效链接
立即抓取 网站 并找到断开的链接 (404) 和服务器错误。批量导出错误和源网址进行修复或发送给开发者。
2、审核重定向
查找临时和永久重定向,识别重定向链和循环,或上传 URL 列表以在网站迁移期间进行审核。
3、分析页面标题和元数据
在抓取过程中分析页面标题和元描述,识别网站过长、缺失、缺失或重复的内容。
4、发现重复内容
使用 md5 算法检查和查找完全重复的 URL、部分重复的元素(例如页面标题、描述或标题)并查找低内容页面。
5、使用XPath提取数据
使用 CSS Path、XPath 或正则表达式从网页的 HTML 中采集任何数据。这可能包括社交元标签、其他标题、价格、SKU 或更多!
6、查看机器人和说明
查看被 robots.txt、元机器人或 X-Robots-Tag 指令(例如“noindex”或“nofollow”)以及规范和 rel="next" 和 rel="prev" 阻止的 URL。
7、生成 XML 站点地图
快速创建 XML 站点地图和图片 XML 站点地图,并通过 URL 进行高级配置,包括最后修改、优先级和更改频率。
8、与 Google Analytics 集成
连接到 Google Analytics API 并获取用于抓取功能的用户数据,例如会话或跳出率以及着陆页的转化、目标、交易和收入。
9、抓取 JavaScript网站
使用集成的 Chromium WRS 来渲染网页以抓取动态的、富含 JavaScript 的 网站 和框架,例如 Angular、React 和 Vue.js。
10、可视化网站架构
使用交互式爬虫和目录强制地图和树形地图站点来直观地评估内部链接和 URL 结构。
Screaming Frog SEO Spider for Mac 快速总结
错误 - 客户端错误,例如断开的链接和服务器错误(无响应、4XX、5XX)。
永久重定向、临时重定向(3XX 响应)和 JS 重定向。
被阻止的网址 - robots.txt 协议不允许查看和审查网址。
被阻止的资源 - 在演示模式下查看和审核被阻止的资源。
外部链接-所有外部链接及其状态代码。
协议 - URL 是安全 (HTTP) 还是不安全 (HTTP)。
URI 问题 - 非 ASCII 字符、下划线、大写字符、参数或长 URL。
重复页面-哈希/MD5校验和算法来检查完全重复的页面。
页面标题缺失、重复、超过65个字符、较短、像素宽度被截断、等于或大于h1。
元描述-缺失、重复、超过 156 个字符、短、截断或像素宽度多。
元关键字 - 主要供参考,因为它们未被 Google、Bing 或 Yahoo 使用。
文件大小-网址和图片的大小。
响应时间。
最后修改的标题。
页面(抓取)深度。
字数统计。
H1-缺失,重复,超过70个字符,不止一个。
H2-缺失,重复,超过70个字符,不止一个。
元机器人索引、无索引、follow、nofollow、noarchive、nosnippet、noodp、noydir等
元刷新——包括目标页面和时间延迟。
ajax抓取网页内容(目标网络爬虫的是做什么的?手动写一个简单的网络)
网站优化 • 优采云 发表了文章 • 0 个评论 • 42 次浏览 • 2021-12-31 19:14
目标
网络爬虫有什么作用?手动编写一个简单的网络爬虫;
1. 网络爬虫
1.1. 姓名
1.2. 简介
2.流程
通过上面的流程图,您可以大致了解网络爬虫是做什么的,并基于这些,您可以设计一个简单的网络爬虫。
一个简单的爬虫。必要的功能:
发送请求和获取响应的功能;解析响应的功能;存储过滤数据的功能;处理解析出的URL路径的功能;
2.1. 兴趣点
3. 分类
4. 创意分析
首先观察我们爬虫的起始页面是:
所有喜讯信息的URL用XPath表达式表示://div[@class='main_l']/ul/li
相关数据
好的,我们已经在上面的代码中找到了需要获取的关键信息的XPath表达式,接下来就可以正式编写代码来实现了。
5.代码实现
代码实现部分使用了webmagic框架,因为比使用基本的Java网络编程要简单得多。注意:对于 webmagic 框架,您可以阅读以下讲义
5.1.代码结构
5.2.程序入口
Demo.java
/**
* 程序入口
*/
public class Demo {
public static void main(String[] args) {
// 爬取开始
Spider
// 爬取过程
.create(new WanhoPageProcessor())
// 爬取结果保存
.addPipeline(new WanhoPipeline())
// 爬取的第一个页面
.addUrl("http://www.wanho.net/a/jyxb/")
// 启用的线程数
.thread(5).run();
}
}
5.3.爬取过程
package net.wanho.wanhosite;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.processor.PageProcessor;
import us.codecraft.webmagic.selector.Html;
public class WanhoPageProcessor implements PageProcessor {
// 部分一:抓取网站的相关配置,包括编码、抓取间隔、重试次数等
private Site site = Site
.me()
.setTimeOut(10000)
.setRetryTimes(3)
.setSleepTime(1000)
.setCharset("UTF-8");
// 獲得站點
@Override
public Site getSite() {
return site;
}
//爬取過程
@Override
public void process(Page page) {
//获取当前页的所有喜报
List list = page.getHtml().xpath("//div[@class='main_l']/ul/li").all();
//要保存喜报的集合
Vector voLst = new Vector();
//遍历喜报
String title;
String content;
String img;
for (String item : list) {
Html tmp = Html.create(item);
//标题
title = tmp.xpath("//div[@class='content']/h4/a/text()").toString();
//内容
content = tmp.xpath("//div[@class='content']/p/text()").toString();
//图片路径
img = tmp.xpath("//a/img/@src").toString();
//加入集合
ArticleVo vo = new ArticleVo(title, content, img);
voLst.add(vo);
}
//保存数据至page中,后续进行持久化
page.putField("e_list", voLst);
//加载其它页
page.addTargetRequests( getOtherUrls());
}
//其它页
public List getOtherUrls(){
List urlLsts = new ArrayList();
for(int i=2;i网络选项),然后找到那些加载数据的json请求,最后直接请求那些URL获取数据来模拟浏览器请求,等待一个从满载开始的一定时间 只需从完成的页面中获取数据。这类爬虫通常需要内嵌浏览器内核,如:webmagic、phantom.js、HttpUnit等
接下来,我将通过我们的官网和大家一起分析一下如何实现这样的爬虫:
首先观察我们爬虫的起始页面是:
从上图可以看出,我们可以从首页的HTML源代码中直观的找到我们需要的标题、内容、图片链接等信息。那么我们可以通过什么方式提取这些目标数据呢?
其实提取页面元素的webmagic框架主要支持以下三种方法:
XPath 正则表达式 CSS 选择器
当然,选择哪种方式提取数据需要根据具体页面进行分析。在这个例子中,很明显使用XPath提取数据是最方便的
所以,那我直接给出我们需要爬取的数据的XPath路径:
注:“//”表示从相对路径开始,第一个“/”表示从页面路径开始;两个/后面的内容代表一个元素,括号内的内容表示该元素的执行属性,如:h1[@class='entry-title']表示:有一个h1元素,其class属性为“条目标题”
6.2.3. 页面数据提取:
使用webmagic提取页面数据时,需要自定义一个类来实现PageProcessor接口。
该类实现PageProcessor接口的主要功能如下三步:
爬虫配置:爬取页面的配置,包括编码、爬取间隔、重试次数等页面元素的提取:使用正则表达式或者XPath提取页面元素。新链接的发现:从一个页面找到的链接到其他待抓取的目标页面
<p>package net.wanho.wanhosite;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.processor.PageProcessor;
import us.codecraft.webmagic.selector.Html;
public class WanhoPageProcessor implements PageProcessor {
// 部分一:抓取网站的相关配置,包括编码、抓取间隔、重试次数等
private Site site = Site
.me()
.setTimeOut(10000)
.setRetryTimes(3)
.setSleepTime(1000)
.setCharset("UTF-8");
// 獲得站點
@Override
public Site getSite() {
return site;
}
//爬取過程
@Override
public void process(Page page) {
//获取当前页的所有喜报
List list = page.getHtml().xpath("//div[@class='main_l']/ul/li").all();
//要保存喜报的集合
Vector voLst = new Vector();
//遍历喜报
String title;
String content;
String img;
for (String item : list) {
Html tmp = Html.create(item);
//标题
title = tmp.xpath("//div[@class='content']/h4/a/text()").toString();
//内容
content = tmp.xpath("//div[@class='content']/p/text()").toString();
//图片路径
img = tmp.xpath("//a/img/@src").toString();
//加入集合
ArticleVo vo = new ArticleVo(title, content, img);
voLst.add(vo);
}
//保存数据至page中,后续进行持久化
page.putField("e_list", voLst);
//加载其它页
page.addTargetRequests( getOtherUrls());
}
//其它页
public List getOtherUrls(){
List urlLsts = new ArrayList();
for(int i=2;i 查看全部
ajax抓取网页内容(目标网络爬虫的是做什么的?手动写一个简单的网络)
目标
网络爬虫有什么作用?手动编写一个简单的网络爬虫;
1. 网络爬虫
1.1. 姓名
1.2. 简介
2.流程
通过上面的流程图,您可以大致了解网络爬虫是做什么的,并基于这些,您可以设计一个简单的网络爬虫。
一个简单的爬虫。必要的功能:
发送请求和获取响应的功能;解析响应的功能;存储过滤数据的功能;处理解析出的URL路径的功能;
2.1. 兴趣点
3. 分类
4. 创意分析
首先观察我们爬虫的起始页面是:
所有喜讯信息的URL用XPath表达式表示://div[@class='main_l']/ul/li
相关数据
好的,我们已经在上面的代码中找到了需要获取的关键信息的XPath表达式,接下来就可以正式编写代码来实现了。
5.代码实现
代码实现部分使用了webmagic框架,因为比使用基本的Java网络编程要简单得多。注意:对于 webmagic 框架,您可以阅读以下讲义
5.1.代码结构
5.2.程序入口
Demo.java
/**
* 程序入口
*/
public class Demo {
public static void main(String[] args) {
// 爬取开始
Spider
// 爬取过程
.create(new WanhoPageProcessor())
// 爬取结果保存
.addPipeline(new WanhoPipeline())
// 爬取的第一个页面
.addUrl("http://www.wanho.net/a/jyxb/")
// 启用的线程数
.thread(5).run();
}
}
5.3.爬取过程
package net.wanho.wanhosite;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.processor.PageProcessor;
import us.codecraft.webmagic.selector.Html;
public class WanhoPageProcessor implements PageProcessor {
// 部分一:抓取网站的相关配置,包括编码、抓取间隔、重试次数等
private Site site = Site
.me()
.setTimeOut(10000)
.setRetryTimes(3)
.setSleepTime(1000)
.setCharset("UTF-8");
// 獲得站點
@Override
public Site getSite() {
return site;
}
//爬取過程
@Override
public void process(Page page) {
//获取当前页的所有喜报
List list = page.getHtml().xpath("//div[@class='main_l']/ul/li").all();
//要保存喜报的集合
Vector voLst = new Vector();
//遍历喜报
String title;
String content;
String img;
for (String item : list) {
Html tmp = Html.create(item);
//标题
title = tmp.xpath("//div[@class='content']/h4/a/text()").toString();
//内容
content = tmp.xpath("//div[@class='content']/p/text()").toString();
//图片路径
img = tmp.xpath("//a/img/@src").toString();
//加入集合
ArticleVo vo = new ArticleVo(title, content, img);
voLst.add(vo);
}
//保存数据至page中,后续进行持久化
page.putField("e_list", voLst);
//加载其它页
page.addTargetRequests( getOtherUrls());
}
//其它页
public List getOtherUrls(){
List urlLsts = new ArrayList();
for(int i=2;i网络选项),然后找到那些加载数据的json请求,最后直接请求那些URL获取数据来模拟浏览器请求,等待一个从满载开始的一定时间 只需从完成的页面中获取数据。这类爬虫通常需要内嵌浏览器内核,如:webmagic、phantom.js、HttpUnit等
接下来,我将通过我们的官网和大家一起分析一下如何实现这样的爬虫:
首先观察我们爬虫的起始页面是:
从上图可以看出,我们可以从首页的HTML源代码中直观的找到我们需要的标题、内容、图片链接等信息。那么我们可以通过什么方式提取这些目标数据呢?
其实提取页面元素的webmagic框架主要支持以下三种方法:
XPath 正则表达式 CSS 选择器
当然,选择哪种方式提取数据需要根据具体页面进行分析。在这个例子中,很明显使用XPath提取数据是最方便的
所以,那我直接给出我们需要爬取的数据的XPath路径:
注:“//”表示从相对路径开始,第一个“/”表示从页面路径开始;两个/后面的内容代表一个元素,括号内的内容表示该元素的执行属性,如:h1[@class='entry-title']表示:有一个h1元素,其class属性为“条目标题”
6.2.3. 页面数据提取:
使用webmagic提取页面数据时,需要自定义一个类来实现PageProcessor接口。
该类实现PageProcessor接口的主要功能如下三步:
爬虫配置:爬取页面的配置,包括编码、爬取间隔、重试次数等页面元素的提取:使用正则表达式或者XPath提取页面元素。新链接的发现:从一个页面找到的链接到其他待抓取的目标页面
<p>package net.wanho.wanhosite;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.processor.PageProcessor;
import us.codecraft.webmagic.selector.Html;
public class WanhoPageProcessor implements PageProcessor {
// 部分一:抓取网站的相关配置,包括编码、抓取间隔、重试次数等
private Site site = Site
.me()
.setTimeOut(10000)
.setRetryTimes(3)
.setSleepTime(1000)
.setCharset("UTF-8");
// 獲得站點
@Override
public Site getSite() {
return site;
}
//爬取過程
@Override
public void process(Page page) {
//获取当前页的所有喜报
List list = page.getHtml().xpath("//div[@class='main_l']/ul/li").all();
//要保存喜报的集合
Vector voLst = new Vector();
//遍历喜报
String title;
String content;
String img;
for (String item : list) {
Html tmp = Html.create(item);
//标题
title = tmp.xpath("//div[@class='content']/h4/a/text()").toString();
//内容
content = tmp.xpath("//div[@class='content']/p/text()").toString();
//图片路径
img = tmp.xpath("//a/img/@src").toString();
//加入集合
ArticleVo vo = new ArticleVo(title, content, img);
voLst.add(vo);
}
//保存数据至page中,后续进行持久化
page.putField("e_list", voLst);
//加载其它页
page.addTargetRequests( getOtherUrls());
}
//其它页
public List getOtherUrls(){
List urlLsts = new ArrayList();
for(int i=2;i
ajax抓取网页内容(ajax抓取网页内容的速度与很好的方法-苏州安嘉)
网站优化 • 优采云 发表了文章 • 0 个评论 • 43 次浏览 • 2021-12-31 13:00
ajax抓取网页内容。虽然加载的时间很长,但是在服务器可接受的情况下。这速度还是很好的。这应该算是对的起单价。直接使用网页内容,单价贵了很多。
对于纯粹的页面抓取scrapy是一个好选择。javascript样式加载,可以选择使用presetplus的preset文件或者sit+dom实现。
一楼的意思是只能在浏览器获取,那么:1.爬虫尽量只爬网页的相关结构,请求的文件,解析出来后再提交给后端处理。(做时间规划,把相关的时间分割来完成爬取的过程)2.如果你已经有数据库,直接在数据库取相关数据就行,在请求的时候解析它。3.如果手里没有数据库,那么采用分析对象来抓取(如links,findall,sitemaps等)对象动态变化太多,爬取成本高。
把你需要抓取的部分都放在数据库或是lib上,然后用xpath解析数据,
既然大家都同意用markdown,那么我就用markdown好了。
单纯为了抓取网页内容,单一的ajax抓取已经足够抓取速度快,反正你提交到服务器了,谁有空看你的js,css?我看到的大部分js,css服务器是可以解析的,比如那些网页上foo,bar,goto很多的,百度一下,你就知道。第二个问题是什么时候爬取?是抓取不着的东西吗?那么我的答案是,抓取不着的东西,如果没有时间限制的,在你有时间看的东西,都抓取下来,抓取着不着的东西,尽快丢掉。我并不支持再把什么文件之类的东西备份起来,所以也不存在什么时候发给客户的问题。 查看全部
ajax抓取网页内容(ajax抓取网页内容的速度与很好的方法-苏州安嘉)
ajax抓取网页内容。虽然加载的时间很长,但是在服务器可接受的情况下。这速度还是很好的。这应该算是对的起单价。直接使用网页内容,单价贵了很多。
对于纯粹的页面抓取scrapy是一个好选择。javascript样式加载,可以选择使用presetplus的preset文件或者sit+dom实现。
一楼的意思是只能在浏览器获取,那么:1.爬虫尽量只爬网页的相关结构,请求的文件,解析出来后再提交给后端处理。(做时间规划,把相关的时间分割来完成爬取的过程)2.如果你已经有数据库,直接在数据库取相关数据就行,在请求的时候解析它。3.如果手里没有数据库,那么采用分析对象来抓取(如links,findall,sitemaps等)对象动态变化太多,爬取成本高。
把你需要抓取的部分都放在数据库或是lib上,然后用xpath解析数据,
既然大家都同意用markdown,那么我就用markdown好了。
单纯为了抓取网页内容,单一的ajax抓取已经足够抓取速度快,反正你提交到服务器了,谁有空看你的js,css?我看到的大部分js,css服务器是可以解析的,比如那些网页上foo,bar,goto很多的,百度一下,你就知道。第二个问题是什么时候爬取?是抓取不着的东西吗?那么我的答案是,抓取不着的东西,如果没有时间限制的,在你有时间看的东西,都抓取下来,抓取着不着的东西,尽快丢掉。我并不支持再把什么文件之类的东西备份起来,所以也不存在什么时候发给客户的问题。
ajax抓取网页内容(关于百度搜索引擎工作原理知识,有不少站长SEO还没有)
网站优化 • 优采云 发表了文章 • 0 个评论 • 69 次浏览 • 2021-12-30 15:01
关于百度搜索引擎的工作原理,很多站长都没有仔细阅读和理解SEO。本文讲解了百度蜘蛛爬取系统的原理和索引构建,让SEOer对百度蜘蛛的索引构建有更多的了解。
一、Spider抓取系统的基本框架
互联网信息的爆炸式增长,如何有效地获取和使用这些信息是搜索引擎工作中最重要的环节。数据采集系统作为整个搜索系统的上游,主要负责互联网信息的采集、保存和更新。它像蜘蛛一样在网络中爬行,所以通常被称为“蜘蛛”。比如我们常用的几种常见的搜索引擎蜘蛛叫做:Baiduspdier、Googlebot、搜狗网蜘蛛等。
蜘蛛爬取系统是搜索引擎数据来源的重要保障。如果把网络理解为一个有向图,那么蜘蛛的工作过程可以看作是对这个有向图的一次遍历。从一些重要的种子网址开始,通过页面上的超链接,不断地发现和抓取新的网址,尽可能多地抓取有价值的网页。对于像百度这样的大型蜘蛛系统,由于网页随时都有可能被修改、删除或出现新的超链接,所以需要更新以前蜘蛛爬过的页面,并维护一个URL库和页面库.
下图为蜘蛛爬取系统的基本框架,包括链接存储系统、链接选择系统、dns解析服务系统、爬取调度系统、网页分析系统、链接提取系统、链接分析系统、网页存储系统. 百度蜘蛛通过本系统的配合完成对网页的抓取。
二、百度蜘蛛的主要爬取策略类型
上图看似简单,但Baiduspider在爬取过程中实际上面临着一个超级复杂的网络环境,为了让系统尽可能多的抓取有价值的资源,并保持页面在系统和实际环境中的一致性在同时不会给网站体验带来压力,会设计出多种复杂的爬取策略。以下是简要介绍:
1. 抓取友好
互联网资源的巨大数量级要求抓取系统尽可能高效地使用带宽,在有限的硬件和带宽资源下抓取尽可能多的有价值的资源。这就产生了另一个问题。抓取网站的带宽消耗造成访问压力。如果度数过大,将直接影响抓取网站的正常用户访问行为。因此,在爬取过程中,必须控制一定的爬取压力,以达到不影响用户正常访问网站,抓取尽可能多的有价值资源的目的。
通常,最基本的是基于ip的压力控制。这是因为如果是基于一个域名,可能会出现一个域名对应多个ip(很多大网站)或者多个域名对应同一个ip(小网站共享ip)的问题。在实际中,压力部署控制往往是根据ip和域名的各种情况进行的。同时,站长平台也推出了压力反馈工具。站长可以手动调整自己网站的爬虫压力。此时,百度蜘蛛会根据站长的要求,优先进行爬取压力控制。
同一个站点的抓取速度控制一般分为两类:一类是一段时间内的抓取频率;二是一段时间内的爬取流量。同一个站点的爬取速度在不同的时间会有所不同。例如,在夜晚安静、月亮暗、风大的时候,爬行速度可能会更快。它还取决于特定的站点类型。主要思想是错开正常用户访问的高峰期,不断调整。对于不同的站点,也需要不同的爬取速度。
3、新链接重要性的判断
在建库链接之前,百度蜘蛛会对页面进行初步的内容分析和链接分析,通过内容分析判断网页是否需要建索引库,通过链接分析找到更多的网页,然后抓取更多的网页——分析——是否建库&发现新链接的过程。理论上,百度蜘蛛会检索新页面上所有可以“看到”的链接。那么,面对众多的新链接,百度蜘蛛是根据什么判断哪个更重要呢?两个方面:
首先,对用户的价值是独一无二的。百度搜索引擎喜欢独特的内容突出。不要因为网页的主要内容不突出而被搜索引擎误判为空页和短页。其次,链接很重要。目录级别-站点中浅优先链接的流行度
四、百度优先建设重要图书馆的原则
百度蜘蛛抓取的页面数量并不是最重要的。重要的是一个索引数据库建了多少页,也就是我们常说的“建库”。众所周知,搜索引擎的索引库是分层的。优质的网页会被分配到重要的索引库,普通的网页会留在普通的图书馆,更糟糕的网页会被分配到低级别的图书馆作为补充资料。目前60%的搜索需求只需要调用重要的索引库就可以满足,这也解释了为什么有些网站流量极高却一直不尽人意的原因。
那么,哪些网页可以进入优质索引库呢?其实总的原则是一个:对用户有价值。包括但不仅限于:
及时性和有价值的页面:在这里,及时性和价值并存,缺一不可。有些网站为了生成时间敏感的内容页面,做了大量的采集工作,产生了一堆毫无价值的页面,百度不想看到。优质专题页:专题页内容不一定完全原创,也可以很好的整合各方内容,或者添加一些新鲜的内容,如意见、评论等,为用户提供更丰富、更多的内容内容全面。高价值原创内容页面:百度将原创定义为经过一定成本和大量经验形成的文章。不要问我们伪原创是不是原创。重要的个人页面:这里只是一个例子。科比已经在新浪微博上开设了一个账户。就算他不经常更新,对百度来说也是极其重要的一个页面。5、哪些网页不能建索引库
上述优质网页都被收录在索引库中,但实际上,互联网上的大多数网站根本没有被百度收录。不是百度没找到,而是建库前的筛选链接被过滤掉了。那么一开始过滤掉了什么样的网页:
内容重复的网页:百度无需收录
互联网上已有的内容。主要内容较短的网页使用了百度蜘蛛无法解析的技术,如JS、AJAX等,虽然用户访问时可以看到丰富的内容,但仍会被搜索引擎丢弃。加载速度较慢的网页也可用作将短页面视为空白。请注意,广告的加载时间计为网页的整体加载时间。很多主体不突出的网页,即使被爬回来,也会在这个链接中被丢弃。一些作弊页面
更多关于aiduspider爬取系统原理和索引构建,请到百度站长论坛查看文档。
这篇文章就到此为止,希望能给大家带来一些思考。想学习更多SEO专业知识,可以关注微信公众号:“爱学SEO”,阅读好文章和优质教学视频。 查看全部
ajax抓取网页内容(关于百度搜索引擎工作原理知识,有不少站长SEO还没有)
关于百度搜索引擎的工作原理,很多站长都没有仔细阅读和理解SEO。本文讲解了百度蜘蛛爬取系统的原理和索引构建,让SEOer对百度蜘蛛的索引构建有更多的了解。
一、Spider抓取系统的基本框架
互联网信息的爆炸式增长,如何有效地获取和使用这些信息是搜索引擎工作中最重要的环节。数据采集系统作为整个搜索系统的上游,主要负责互联网信息的采集、保存和更新。它像蜘蛛一样在网络中爬行,所以通常被称为“蜘蛛”。比如我们常用的几种常见的搜索引擎蜘蛛叫做:Baiduspdier、Googlebot、搜狗网蜘蛛等。
蜘蛛爬取系统是搜索引擎数据来源的重要保障。如果把网络理解为一个有向图,那么蜘蛛的工作过程可以看作是对这个有向图的一次遍历。从一些重要的种子网址开始,通过页面上的超链接,不断地发现和抓取新的网址,尽可能多地抓取有价值的网页。对于像百度这样的大型蜘蛛系统,由于网页随时都有可能被修改、删除或出现新的超链接,所以需要更新以前蜘蛛爬过的页面,并维护一个URL库和页面库.
下图为蜘蛛爬取系统的基本框架,包括链接存储系统、链接选择系统、dns解析服务系统、爬取调度系统、网页分析系统、链接提取系统、链接分析系统、网页存储系统. 百度蜘蛛通过本系统的配合完成对网页的抓取。
二、百度蜘蛛的主要爬取策略类型
上图看似简单,但Baiduspider在爬取过程中实际上面临着一个超级复杂的网络环境,为了让系统尽可能多的抓取有价值的资源,并保持页面在系统和实际环境中的一致性在同时不会给网站体验带来压力,会设计出多种复杂的爬取策略。以下是简要介绍:
1. 抓取友好
互联网资源的巨大数量级要求抓取系统尽可能高效地使用带宽,在有限的硬件和带宽资源下抓取尽可能多的有价值的资源。这就产生了另一个问题。抓取网站的带宽消耗造成访问压力。如果度数过大,将直接影响抓取网站的正常用户访问行为。因此,在爬取过程中,必须控制一定的爬取压力,以达到不影响用户正常访问网站,抓取尽可能多的有价值资源的目的。
通常,最基本的是基于ip的压力控制。这是因为如果是基于一个域名,可能会出现一个域名对应多个ip(很多大网站)或者多个域名对应同一个ip(小网站共享ip)的问题。在实际中,压力部署控制往往是根据ip和域名的各种情况进行的。同时,站长平台也推出了压力反馈工具。站长可以手动调整自己网站的爬虫压力。此时,百度蜘蛛会根据站长的要求,优先进行爬取压力控制。
同一个站点的抓取速度控制一般分为两类:一类是一段时间内的抓取频率;二是一段时间内的爬取流量。同一个站点的爬取速度在不同的时间会有所不同。例如,在夜晚安静、月亮暗、风大的时候,爬行速度可能会更快。它还取决于特定的站点类型。主要思想是错开正常用户访问的高峰期,不断调整。对于不同的站点,也需要不同的爬取速度。

3、新链接重要性的判断
在建库链接之前,百度蜘蛛会对页面进行初步的内容分析和链接分析,通过内容分析判断网页是否需要建索引库,通过链接分析找到更多的网页,然后抓取更多的网页——分析——是否建库&发现新链接的过程。理论上,百度蜘蛛会检索新页面上所有可以“看到”的链接。那么,面对众多的新链接,百度蜘蛛是根据什么判断哪个更重要呢?两个方面:
首先,对用户的价值是独一无二的。百度搜索引擎喜欢独特的内容突出。不要因为网页的主要内容不突出而被搜索引擎误判为空页和短页。其次,链接很重要。目录级别-站点中浅优先链接的流行度

四、百度优先建设重要图书馆的原则
百度蜘蛛抓取的页面数量并不是最重要的。重要的是一个索引数据库建了多少页,也就是我们常说的“建库”。众所周知,搜索引擎的索引库是分层的。优质的网页会被分配到重要的索引库,普通的网页会留在普通的图书馆,更糟糕的网页会被分配到低级别的图书馆作为补充资料。目前60%的搜索需求只需要调用重要的索引库就可以满足,这也解释了为什么有些网站流量极高却一直不尽人意的原因。
那么,哪些网页可以进入优质索引库呢?其实总的原则是一个:对用户有价值。包括但不仅限于:
及时性和有价值的页面:在这里,及时性和价值并存,缺一不可。有些网站为了生成时间敏感的内容页面,做了大量的采集工作,产生了一堆毫无价值的页面,百度不想看到。优质专题页:专题页内容不一定完全原创,也可以很好的整合各方内容,或者添加一些新鲜的内容,如意见、评论等,为用户提供更丰富、更多的内容内容全面。高价值原创内容页面:百度将原创定义为经过一定成本和大量经验形成的文章。不要问我们伪原创是不是原创。重要的个人页面:这里只是一个例子。科比已经在新浪微博上开设了一个账户。就算他不经常更新,对百度来说也是极其重要的一个页面。5、哪些网页不能建索引库
上述优质网页都被收录在索引库中,但实际上,互联网上的大多数网站根本没有被百度收录。不是百度没找到,而是建库前的筛选链接被过滤掉了。那么一开始过滤掉了什么样的网页:
内容重复的网页:百度无需收录
互联网上已有的内容。主要内容较短的网页使用了百度蜘蛛无法解析的技术,如JS、AJAX等,虽然用户访问时可以看到丰富的内容,但仍会被搜索引擎丢弃。加载速度较慢的网页也可用作将短页面视为空白。请注意,广告的加载时间计为网页的整体加载时间。很多主体不突出的网页,即使被爬回来,也会在这个链接中被丢弃。一些作弊页面
更多关于aiduspider爬取系统原理和索引构建,请到百度站长论坛查看文档。
这篇文章就到此为止,希望能给大家带来一些思考。想学习更多SEO专业知识,可以关注微信公众号:“爱学SEO”,阅读好文章和优质教学视频。
ajax抓取网页内容(【Python之Ajax数据爬取】照Web发展的趋势)
网站优化 • 优采云 发表了文章 • 0 个评论 • 47 次浏览 • 2021-12-27 04:21
Python 的 Ajax 数据爬网介绍
有时我们使用requests获取网页时,得到的结果可能与浏览器中看到的不同:在浏览器中可以看到正常显示的页面数据,但是使用requests获取的结果却看不到。
这是因为请求获取的数据都是原创
HTML文档,浏览器中的页面是JavaScript处理数据后生成的结果。这些数据的来源有很多,可能是通过Ajax加载的,也可能是收录
在HTML文档中,也可能是通过JavaScript和特定算法计算后生成的。
对于第一种情况,数据加载是一种异步加载方式。原创
页面最初不会收录
一些数据。原创
页面加载完毕后,会请求一个接口,从服务器获取数据,然后将数据进行处理,呈现在网页上,这其实就是一个ajax请求。
根据Web的发展趋势,这种形式的页面越来越多。网页的原创
HTML 文档不收录
任何数据。数据通过Ajax统一加载后呈现,使得Web开发中的左前后端分离,减少了服务器直接渲染页面的压力。
所以如果遇到这样的页面,可以直接使用requests等库来抓取原创
网页,无法获取有效数据。这时候就需要从网页后台分析发送到界面的Ajax请求。如果可以使用requests来模拟ajax请求,那么就可以爬取成功。
什么是阿贾克斯?
Ajax,全称Asynchronous JavaScript and XML,即异步JavaScript和XML。它不是一种编程语言,而是一种使用 JavaScript 与服务器交换数据并更新部分网页的技术,同时确保页面不会被刷新,页面链接不会发生变化。
对于传统网页,如果要更新其内容,必须刷新整个页面,而使用Ajax,可以在不刷新页面的情况下更新其内容。在这个过程中,页面实际上是在后台与服务器进行交互。获取到数据后,通过JavaScript来改变网页,从而更新网页的内容。
1.实例介绍
在浏览网页时,我们会发现很多网页都有向下滚动查看更多选项。比如下面这个腾讯新闻网站一直在下降,可以发现,下降了几个新闻之后,就不再下线了。相反,将出现加载动画。一段时间后,新的新闻内容将继续出现在下方。这个过程其实就是Ajax加载的过程。
我们注意到页面没有完全刷新,这意味着页面上的链接没有改变,但页面上有更多的新内容,也就是后来发布的新消息。这是获取新数据并通过 Ajax 呈现的过程。
2.基本原则
初步了解了 Ajax 之后,我们再来了解一下它的基本原理。向网页更新发送ajax请求的过程可以简单分为以下3个步骤:
(1) 发送请求;
(2)分析内容;
(3) 渲染网页。 查看全部
ajax抓取网页内容(【Python之Ajax数据爬取】照Web发展的趋势)
Python 的 Ajax 数据爬网介绍
有时我们使用requests获取网页时,得到的结果可能与浏览器中看到的不同:在浏览器中可以看到正常显示的页面数据,但是使用requests获取的结果却看不到。
这是因为请求获取的数据都是原创
HTML文档,浏览器中的页面是JavaScript处理数据后生成的结果。这些数据的来源有很多,可能是通过Ajax加载的,也可能是收录
在HTML文档中,也可能是通过JavaScript和特定算法计算后生成的。
对于第一种情况,数据加载是一种异步加载方式。原创
页面最初不会收录
一些数据。原创
页面加载完毕后,会请求一个接口,从服务器获取数据,然后将数据进行处理,呈现在网页上,这其实就是一个ajax请求。
根据Web的发展趋势,这种形式的页面越来越多。网页的原创
HTML 文档不收录
任何数据。数据通过Ajax统一加载后呈现,使得Web开发中的左前后端分离,减少了服务器直接渲染页面的压力。
所以如果遇到这样的页面,可以直接使用requests等库来抓取原创
网页,无法获取有效数据。这时候就需要从网页后台分析发送到界面的Ajax请求。如果可以使用requests来模拟ajax请求,那么就可以爬取成功。
什么是阿贾克斯?
Ajax,全称Asynchronous JavaScript and XML,即异步JavaScript和XML。它不是一种编程语言,而是一种使用 JavaScript 与服务器交换数据并更新部分网页的技术,同时确保页面不会被刷新,页面链接不会发生变化。
对于传统网页,如果要更新其内容,必须刷新整个页面,而使用Ajax,可以在不刷新页面的情况下更新其内容。在这个过程中,页面实际上是在后台与服务器进行交互。获取到数据后,通过JavaScript来改变网页,从而更新网页的内容。
1.实例介绍
在浏览网页时,我们会发现很多网页都有向下滚动查看更多选项。比如下面这个腾讯新闻网站一直在下降,可以发现,下降了几个新闻之后,就不再下线了。相反,将出现加载动画。一段时间后,新的新闻内容将继续出现在下方。这个过程其实就是Ajax加载的过程。

我们注意到页面没有完全刷新,这意味着页面上的链接没有改变,但页面上有更多的新内容,也就是后来发布的新消息。这是获取新数据并通过 Ajax 呈现的过程。
2.基本原则
初步了解了 Ajax 之后,我们再来了解一下它的基本原理。向网页更新发送ajax请求的过程可以简单分为以下3个步骤:
(1) 发送请求;
(2)分析内容;
(3) 渲染网页。
ajax抓取网页内容(Pythonselenium3.14为什么selenium不能直接拦截请求呢?(图))
网站优化 • 优采云 发表了文章 • 0 个评论 • 55 次浏览 • 2021-12-27 00:04
部门需要一个自动化脚本来完成web端接口功能的冒烟,需要在页面加载时抓取ajax请求,从接口层面判断请求是否成功。查阅了大量资料,没有人有处理相关问题的经验,过程中坑也很多,所以如果你也有这个需求,继续往下看吧~
环境和语言:
Python
硒3.14
为什么selenium不能直接拦截请求体?这是Chrome官方故意做的。详情请参考此网址:
%20response%20body&can=1
在网上搜索后,找到了三种解决方法:
1、 取代理,拦截代理级别的日志请求;如果proxy过期了,请求会变得很慢,所以没有采用,有需要的可以自己研究。
2、使用硒线。这是 GitHub 上的一个开源项目。可以直接拦截response_code和body。原理大概就是看源码了。它也应该是一个代理,但这个项目是为你打包的。
当时看到真的很激动,所有的问题都通过pip install解决了。但是当我怀着极大的兴趣运行代码时,发现网页报错:err_proxy_connection_failed。感觉莫名其妙,跑到开源项目中寻找答案。这不仅发生在我身上,也可以说是这个开源项目的一个bug。到目前为止还没有关闭。我很久没有放弃调试,但是这条路走不通,只好流泪放弃。事实证明,不要只相信一颗星星只有一两百颗星星。开源代码放在下面,万一你能通过:
3、开启selenium性能捕获,可以在性能日志中进行修改拦截response_body:
先总结一下总体思路:
结合selenium和Chrome devtool:selenium可以打开性能日志,根据性能日志中的Network.responseReceived事件抓取requestId和对应的url,然后结合selenium提供的execute方法传入requestId参数来获取相应的身体反应。
execute_cdp_cmd()方法的源码里有例子,讲的很清楚,可以去看看。本文还将给出代码示例:
1 caps = DesiredCapabilities.CHROME
2 caps['goog:loggingPrefs'] = {'performance': 'ALL'}
3
4 def driver():
5 global driver
6 driver = webdriver.Chrome(desired_capabilities=caps)
7 driver.maximize_window()
请注意第二行代码,这是我踩到的第一个坑:
很多教程中给出的代码如下:
caps['loggingPrefs'] = {'performance':'ALL'},用这段代码打开性能日志,但是这样运行会报错,原因来自chromedriver,75.< @k27@从>3770.8开始,一定要这样运行。
注意只打开性能日志还是不能抓到正文。如果你的需求只是判断状态码,那么上面的方案就足够了。
1、为什么需要获取requestid:
Chrome性能日志的获取需要配合Chrome DevTool方法使用。本文档详细列出了 Chrome 提供的域。在域网络下,您可以选择所需的方法:
在这里,我选择了我需要的方法,如下图所示,可以看到,这里需要传入一个名为requestId的参数,它是唯一的请求ID,当我们可以抓取到我们想要的body时我们明白了。但我从未听说过这个 requestId。我可以从哪里得到它?这时候就需要对抓取到的性能日志中的事件进行分析。
2、 关于Chrome返回的日志事件,可以参与这个博客,里面有详细的介绍。基于这个博客(.),我分析了我要使用的事件-Network.responseReceived,其中收录
requestid。返回值。
1 def parse_response_body(driver):
2 """获取requestid"""
3 browser_log = driver.get_log('performance')
4 events = [_process_browser_log_entry(entry) for entry in browser_log]
5 events_response = [event for event in events if 'Network.responseReceived' == event['method']] # 根据Network.responseReceived这个network,解析出requestId
6 for res in events_response:
7 requestId = res["params"]["requestId"]
3、总结一下,结合selenium中的方法:
1 def execute_cdp_cmd(driver, cmd, cmd_args):
2 return driver.execute("executeCdpCommand", {'cmd': cmd, 'params': cmd_args})['value']
3
4
5 response_body = driver.execute_cdp_cmd('Network.getResponseBody', {'requestId': requestId}
接下来就很简单了,抓取body,然后用json解析。就在我满怀信心的时候,现实又给了我沉重的一击。在抓取请求体的过程中,程序报错。
未找到具有给定标识符的资源
这是我踩过的最大的坑。它困扰了我五六个小时。我以为是我的代码有问题。一直在调试,在网上找问题,最后在一篇不太相关的js博客里。对于这句话:getResponseBody will error发生在查询什么都不返回时...
回到界面,手动获取了当前运行页面的ajax请求,结果都是没有返回体的请求ORZ。
果断地尝试……除了……,然后程序运行得很漂亮!此刻的心情真是激动的想哭。
后记:
这种需求感觉很普遍。毕竟界面元素能不能加载成功,是看界面返回最直接可靠的方式,但是不知道为什么国内好像没有相关的博客(可能是我没有搜索过了)。所以想记录下这篇文章,希望有需要的朋友不要走那么多弯路,轻松解决问题~~
PS:在FQ的过程中,我也找到了将selenium升级到4的方案,因为selenium 4开始和Chrome DevTools一起支持收购了。但是,只找到了 Java 示例。因为对Java不是很熟悉,所以被抛弃了。他们在这里为每个人提供。如果你需要它,你可以拿起它:
@ohanaadi/chrome-devtools-and-selenium-4-eadab5d755b7
-----------------------我是分割线 2021/02/01----------------- - ---------
今天在看技术博客的时候发现了一个开源项目,是一个被proxy拦截的ajax请求。先记录一下信息: 查看全部
ajax抓取网页内容(Pythonselenium3.14为什么selenium不能直接拦截请求呢?(图))
部门需要一个自动化脚本来完成web端接口功能的冒烟,需要在页面加载时抓取ajax请求,从接口层面判断请求是否成功。查阅了大量资料,没有人有处理相关问题的经验,过程中坑也很多,所以如果你也有这个需求,继续往下看吧~
环境和语言:
Python
硒3.14
为什么selenium不能直接拦截请求体?这是Chrome官方故意做的。详情请参考此网址:
%20response%20body&can=1
在网上搜索后,找到了三种解决方法:
1、 取代理,拦截代理级别的日志请求;如果proxy过期了,请求会变得很慢,所以没有采用,有需要的可以自己研究。
2、使用硒线。这是 GitHub 上的一个开源项目。可以直接拦截response_code和body。原理大概就是看源码了。它也应该是一个代理,但这个项目是为你打包的。
当时看到真的很激动,所有的问题都通过pip install解决了。但是当我怀着极大的兴趣运行代码时,发现网页报错:err_proxy_connection_failed。感觉莫名其妙,跑到开源项目中寻找答案。这不仅发生在我身上,也可以说是这个开源项目的一个bug。到目前为止还没有关闭。我很久没有放弃调试,但是这条路走不通,只好流泪放弃。事实证明,不要只相信一颗星星只有一两百颗星星。开源代码放在下面,万一你能通过:
3、开启selenium性能捕获,可以在性能日志中进行修改拦截response_body:
先总结一下总体思路:
结合selenium和Chrome devtool:selenium可以打开性能日志,根据性能日志中的Network.responseReceived事件抓取requestId和对应的url,然后结合selenium提供的execute方法传入requestId参数来获取相应的身体反应。
execute_cdp_cmd()方法的源码里有例子,讲的很清楚,可以去看看。本文还将给出代码示例:
1 caps = DesiredCapabilities.CHROME
2 caps['goog:loggingPrefs'] = {'performance': 'ALL'}
3
4 def driver():
5 global driver
6 driver = webdriver.Chrome(desired_capabilities=caps)
7 driver.maximize_window()
请注意第二行代码,这是我踩到的第一个坑:
很多教程中给出的代码如下:
caps['loggingPrefs'] = {'performance':'ALL'},用这段代码打开性能日志,但是这样运行会报错,原因来自chromedriver,75.< @k27@从>3770.8开始,一定要这样运行。
注意只打开性能日志还是不能抓到正文。如果你的需求只是判断状态码,那么上面的方案就足够了。
1、为什么需要获取requestid:
Chrome性能日志的获取需要配合Chrome DevTool方法使用。本文档详细列出了 Chrome 提供的域。在域网络下,您可以选择所需的方法:
在这里,我选择了我需要的方法,如下图所示,可以看到,这里需要传入一个名为requestId的参数,它是唯一的请求ID,当我们可以抓取到我们想要的body时我们明白了。但我从未听说过这个 requestId。我可以从哪里得到它?这时候就需要对抓取到的性能日志中的事件进行分析。

2、 关于Chrome返回的日志事件,可以参与这个博客,里面有详细的介绍。基于这个博客(.),我分析了我要使用的事件-Network.responseReceived,其中收录
requestid。返回值。
1 def parse_response_body(driver):
2 """获取requestid"""
3 browser_log = driver.get_log('performance')
4 events = [_process_browser_log_entry(entry) for entry in browser_log]
5 events_response = [event for event in events if 'Network.responseReceived' == event['method']] # 根据Network.responseReceived这个network,解析出requestId
6 for res in events_response:
7 requestId = res["params"]["requestId"]
3、总结一下,结合selenium中的方法:
1 def execute_cdp_cmd(driver, cmd, cmd_args):
2 return driver.execute("executeCdpCommand", {'cmd': cmd, 'params': cmd_args})['value']
3
4
5 response_body = driver.execute_cdp_cmd('Network.getResponseBody', {'requestId': requestId}
接下来就很简单了,抓取body,然后用json解析。就在我满怀信心的时候,现实又给了我沉重的一击。在抓取请求体的过程中,程序报错。
未找到具有给定标识符的资源
这是我踩过的最大的坑。它困扰了我五六个小时。我以为是我的代码有问题。一直在调试,在网上找问题,最后在一篇不太相关的js博客里。对于这句话:getResponseBody will error发生在查询什么都不返回时...
回到界面,手动获取了当前运行页面的ajax请求,结果都是没有返回体的请求ORZ。
果断地尝试……除了……,然后程序运行得很漂亮!此刻的心情真是激动的想哭。
后记:
这种需求感觉很普遍。毕竟界面元素能不能加载成功,是看界面返回最直接可靠的方式,但是不知道为什么国内好像没有相关的博客(可能是我没有搜索过了)。所以想记录下这篇文章,希望有需要的朋友不要走那么多弯路,轻松解决问题~~
PS:在FQ的过程中,我也找到了将selenium升级到4的方案,因为selenium 4开始和Chrome DevTools一起支持收购了。但是,只找到了 Java 示例。因为对Java不是很熟悉,所以被抛弃了。他们在这里为每个人提供。如果你需要它,你可以拿起它:
@ohanaadi/chrome-devtools-and-selenium-4-eadab5d755b7
-----------------------我是分割线 2021/02/01----------------- - ---------
今天在看技术博客的时候发现了一个开源项目,是一个被proxy拦截的ajax请求。先记录一下信息:
ajax抓取网页内容(FacebookWard的解决方法及解决办法)
网站优化 • 优采云 发表了文章 • 0 个评论 • 56 次浏览 • 2021-12-26 18:09
大家在浏览Facebook相册的时候有没有注意到,页面部分刷新时地址栏中的地址也发生了变化,并不是hash方法。它使用了 HTML5 历史上的几个新 API。作为窗口的全局变量,历史在 HTML4 时代并不是什么新鲜事。我们经常使用 history.back() 和 history.go()。
一直觉得没办法,直到两天前看到Discourse创始人之一Robin Ward的解决方案,忍不住尖叫起来。
Discourse 是一个严重依赖 Ajax 的论坛程序,但它必须被 Google 收录。它的解决方案是放弃hash结构,使用History API。
所谓History API,就是在不刷新页面的情况下,改变浏览器地址栏中显示的URL(准确的说是改变网页的当前状态)。这是一个示例,您单击上面的按钮开始播放音乐。然后,点击下面的链接看看发生了什么?
地址栏中的网址已更改,但音乐播放并未中断!
对 History API 的详细介绍超出了本文的范围。简单的说到这里,它的作用就是给浏览器的History对象添加一条记录。
window.history.pushState(state object, title, url);
上面这行命令可以让地址栏中出现一个新的 URL。History对象的pushState方法接受三个参数,新的URL为第三个参数,前两个参数可以为null。
window.history.pushState(null, null, newURL);
目前主流浏览器都支持这种方式:Chrome(26.0+)、Firefox(20.0+)、IE(10.0+)、Safari(5.1+)、歌剧 (12.1+)。
这是罗宾沃德的方法。
首先用History API替换hash结构,让每一个hash符号变成一个正常路径的URL,这样搜索引擎就会抓取每一个网页。
/1
/2
/3
然后,定义一个 JavaScript 函数来处理 Ajax 部分并根据 URL 抓取内容(假设使用 jQuery)。
function anchorClick(link) {
var linkSplit = link.split('/').pop();
$.get('api/' + linkSplit, function(data) {
$('#content').html(data);
});
}
然后定义鼠标的点击事件。
$('#container').on('click', 'a', function(e) {
window.history.pushState(null, null, $(this).attr('href'));
anchorClick($(this).attr('href'));
e.preventDefault();
});
还要考虑用户点击浏览器的“前进/后退”按钮。这时候会触发History对象的popstate事件。
window.addEventListener('popstate', function(e) {
anchorClick(location.pathname);
});
定义以上三段代码后,无需刷新页面即可显示正常路径URL和AJAX内容。
最后,设置服务器端。
因为没有使用 hashtag 结构,所以每个 URL 都是不同的请求。因此,服务器需要向所有这些请求返回具有以下结构的网页,以防止 404 错误。
... ...
如果你仔细看上面的代码,你会发现里面有一个 noscript 标签。这就是秘密。
我们将所有要被搜索引擎收录的内容放在 noscript 标签中。在这种情况下,用户仍然可以在不刷新页面的情况下执行 AJAX 操作,但是搜索引擎会收录
每个页面的主要内容! 查看全部
ajax抓取网页内容(FacebookWard的解决方法及解决办法)
大家在浏览Facebook相册的时候有没有注意到,页面部分刷新时地址栏中的地址也发生了变化,并不是hash方法。它使用了 HTML5 历史上的几个新 API。作为窗口的全局变量,历史在 HTML4 时代并不是什么新鲜事。我们经常使用 history.back() 和 history.go()。
一直觉得没办法,直到两天前看到Discourse创始人之一Robin Ward的解决方案,忍不住尖叫起来。

Discourse 是一个严重依赖 Ajax 的论坛程序,但它必须被 Google 收录。它的解决方案是放弃hash结构,使用History API。
所谓History API,就是在不刷新页面的情况下,改变浏览器地址栏中显示的URL(准确的说是改变网页的当前状态)。这是一个示例,您单击上面的按钮开始播放音乐。然后,点击下面的链接看看发生了什么?

地址栏中的网址已更改,但音乐播放并未中断!
对 History API 的详细介绍超出了本文的范围。简单的说到这里,它的作用就是给浏览器的History对象添加一条记录。
window.history.pushState(state object, title, url);
上面这行命令可以让地址栏中出现一个新的 URL。History对象的pushState方法接受三个参数,新的URL为第三个参数,前两个参数可以为null。
window.history.pushState(null, null, newURL);
目前主流浏览器都支持这种方式:Chrome(26.0+)、Firefox(20.0+)、IE(10.0+)、Safari(5.1+)、歌剧 (12.1+)。
这是罗宾沃德的方法。
首先用History API替换hash结构,让每一个hash符号变成一个正常路径的URL,这样搜索引擎就会抓取每一个网页。
/1
/2
/3
然后,定义一个 JavaScript 函数来处理 Ajax 部分并根据 URL 抓取内容(假设使用 jQuery)。
function anchorClick(link) {
var linkSplit = link.split('/').pop();
$.get('api/' + linkSplit, function(data) {
$('#content').html(data);
});
}
然后定义鼠标的点击事件。
$('#container').on('click', 'a', function(e) {
window.history.pushState(null, null, $(this).attr('href'));
anchorClick($(this).attr('href'));
e.preventDefault();
});
还要考虑用户点击浏览器的“前进/后退”按钮。这时候会触发History对象的popstate事件。
window.addEventListener('popstate', function(e) {
anchorClick(location.pathname);
});
定义以上三段代码后,无需刷新页面即可显示正常路径URL和AJAX内容。
最后,设置服务器端。
因为没有使用 hashtag 结构,所以每个 URL 都是不同的请求。因此,服务器需要向所有这些请求返回具有以下结构的网页,以防止 404 错误。
... ...
如果你仔细看上面的代码,你会发现里面有一个 noscript 标签。这就是秘密。
我们将所有要被搜索引擎收录的内容放在 noscript 标签中。在这种情况下,用户仍然可以在不刷新页面的情况下执行 AJAX 操作,但是搜索引擎会收录
每个页面的主要内容!
ajax抓取网页内容(程序中使用functionGetHtml获得的网页源码中并不会更新内容)
网站优化 • 优采云 发表了文章 • 0 个评论 • 62 次浏览 • 2021-12-21 23:06
使用程序中的TWebbrowser控件或Indy中的控件使用Ajax技术连接网页,获取的网页源代码不会收录任何客户端更新。同理,在IE浏览器中查看源文件时也看不到Ajax更新的内容。通过插件可以看到Ajax的更新内容。问题是如何在程序中获取完整的网页内容?
如果有 Ajax 更新,则不会触发 Webbrowser 的 DocumentComplete 事件。
其实,完整的网页内容并非不可用,只需使用一个简单的方法:
函数 GetHtml(const WebBrowser:TWebBrowser): 字符串;
无功
文档:IHTMLDocument2;
开始
Doc := WebBrowser.Document as IHTMLDocument2;
如果已分配(Doc) 和已分配(Doc.body) 那么
结果:= Doc.body.OuterHtml; //也可以使用innerHTML来获取它的HTML文本
结尾;
这样得到的HTML内容收录了Ajax更新的内容。
现在关键是没有什么好的方法可以判断Ajax是否更新了,因为是异步更新,所以判断起来比较困难。我在互联网上搜索。国外好像有更复杂的解决方案,我也没有研究过是否可行。
我做过网页内容采集软件,不知道有没有好的处理方法,欢迎指教。:-) 查看全部
ajax抓取网页内容(程序中使用functionGetHtml获得的网页源码中并不会更新内容)
使用程序中的TWebbrowser控件或Indy中的控件使用Ajax技术连接网页,获取的网页源代码不会收录任何客户端更新。同理,在IE浏览器中查看源文件时也看不到Ajax更新的内容。通过插件可以看到Ajax的更新内容。问题是如何在程序中获取完整的网页内容?
如果有 Ajax 更新,则不会触发 Webbrowser 的 DocumentComplete 事件。
其实,完整的网页内容并非不可用,只需使用一个简单的方法:
函数 GetHtml(const WebBrowser:TWebBrowser): 字符串;
无功
文档:IHTMLDocument2;
开始
Doc := WebBrowser.Document as IHTMLDocument2;
如果已分配(Doc) 和已分配(Doc.body) 那么
结果:= Doc.body.OuterHtml; //也可以使用innerHTML来获取它的HTML文本
结尾;
这样得到的HTML内容收录了Ajax更新的内容。
现在关键是没有什么好的方法可以判断Ajax是否更新了,因为是异步更新,所以判断起来比较困难。我在互联网上搜索。国外好像有更复杂的解决方案,我也没有研究过是否可行。
我做过网页内容采集软件,不知道有没有好的处理方法,欢迎指教。:-)
ajax抓取网页内容(越来越+感叹号的解决方法放弃井号结构的url结构)
网站优化 • 优采云 发表了文章 • 0 个评论 • 50 次浏览 • 2021-12-21 01:09
越来越多的网站开始采用“单页应用”。
整个网站只有一个网页,使用ajax技术根据用户的输入加载不同的内容。
这种方式的优点是用户体验好,节省流量。缺点是ajax内容无法被搜索引擎抓取。例如,您有一个 网站。
http://www.51sjk.com/Upload/Ar ... 7.com
用户可以通过hash结构的url看到不同的内容。
http://www.51sjk.com/Upload/Ar ... m%231 http://www.51sjk.com/Upload/Ar ... m%232 http://www.51sjk.com/Upload/Ar ... m%233
但是,搜索引擎只会抓取并忽略井号,因此它们无法索引内容。
为了解决这个问题,谷歌提出了“井号+感叹号”的结构。
http://www.51sjk.com/Upload/Ar ... 3%211
当谷歌找到上述网址时,它会自动抓取另一个网址:
http://www.51sjk.com/Upload/Ar ... _%3D1
只要把ajax内容放到这个网址,google就会收录。但问题是“哈希+感叹号”非常丑陋和繁琐。Twitter曾经使用这种结构,它把
http://www.51sjk.com/Upload/Ar ... 9.jpg
改成
http://www.51sjk.com/Upload/Ar ... 4.jpg
结果,用户抱怨连连,只用了半年时间就废了。
那么,有没有什么办法可以让搜索引擎在保持更直观的URL的同时抓取ajax内容呢?
一直觉得没有办法,直到两天前看到话语创始人之一罗宾·沃德的解决方案,我才忍不住尖叫起来。
Discourse是一个严重依赖ajax的论坛程序,但它必须让google收录内容。它的解决方案是放弃hash结构,采用history api。
所谓history api,是指在不刷新页面的情况下,改变浏览器地址栏中显示的url(准确的说,就是改变网页的当前状态)。这是一个示例,您单击上面的按钮开始播放音乐。然后,点击下面的链接看看发生了什么?
地址栏的url变了,但音乐播放不中断!
history api的详细介绍超出了本文章的范围。简单来说,它的作用就是给浏览器的history对象添加一条记录。
window.history.pushstate(state object, title, url);
上面这行命令可以让地址栏中出现一个新的 URL。history对象的pushstate方法接受三个参数,new url为第三个参数,前两个参数可以为null。
window.history.pushstate(null, null, newurl);
目前主流浏览器都支持这种方式:chrome(26.0+)、firefox(20.0+)、ie(10.0+)、safari(5.1+),歌剧(12.1+)。
下面是robin ward的方法。
首先,将hash结构替换成history api,让每个hash符号变成一个正常路径的url,这样搜索引擎就会抓取每一个网页。
example.com/1 example.com/2 example.com/3
然后,定义一个javascript函数来处理ajax部分并根据URL抓取内容(假设使用jquery)。
function anchorclick(link) {
var linksplit = link.split('/').pop();
$.get('api/' + linksplit, function(data) {
$('#content').html(data);
});
}
然后定义鼠标的点击事件。
$('#container').on('click', 'a', function(e) {
window.history.pushstate(null, null, $(this).attr('href'));
anchorclick($(this).attr('href'));
e.preventdefault();
});
还要考虑用户点击浏览器的“前进/后退”按钮。这时候会触发history对象的popstate事件。
window.addeventlistener('popstate', function(e) {
anchorclick(location.pathname);
});
定义以上三段代码后,无需刷新页面即可显示正常路径url和ajax内容。
最后,设置服务器端。
因为没有使用 hashtag 结构,所以每个 URL 都是不同的请求。因此,服务器需要向所有这些请求返回具有以下结构的网页,以防止 404 错误。
... ...
如果你仔细看上面的代码,你会发现里面有一个 noscript 标签。这就是秘密。
我们将所有我们想要搜索引擎的内容放在了 noscript 标签中。在这种情况下,用户仍然可以在不刷新页面的情况下进行ajax操作,但是搜索引擎会收录每个页面的主要内容! 查看全部
ajax抓取网页内容(越来越+感叹号的解决方法放弃井号结构的url结构)
越来越多的网站开始采用“单页应用”。
整个网站只有一个网页,使用ajax技术根据用户的输入加载不同的内容。

这种方式的优点是用户体验好,节省流量。缺点是ajax内容无法被搜索引擎抓取。例如,您有一个 网站。
http://www.51sjk.com/Upload/Ar ... 7.com
用户可以通过hash结构的url看到不同的内容。
http://www.51sjk.com/Upload/Ar ... m%231 http://www.51sjk.com/Upload/Ar ... m%232 http://www.51sjk.com/Upload/Ar ... m%233
但是,搜索引擎只会抓取并忽略井号,因此它们无法索引内容。
为了解决这个问题,谷歌提出了“井号+感叹号”的结构。
http://www.51sjk.com/Upload/Ar ... 3%211
当谷歌找到上述网址时,它会自动抓取另一个网址:
http://www.51sjk.com/Upload/Ar ... _%3D1
只要把ajax内容放到这个网址,google就会收录。但问题是“哈希+感叹号”非常丑陋和繁琐。Twitter曾经使用这种结构,它把
http://www.51sjk.com/Upload/Ar ... 9.jpg
改成
http://www.51sjk.com/Upload/Ar ... 4.jpg
结果,用户抱怨连连,只用了半年时间就废了。
那么,有没有什么办法可以让搜索引擎在保持更直观的URL的同时抓取ajax内容呢?
一直觉得没有办法,直到两天前看到话语创始人之一罗宾·沃德的解决方案,我才忍不住尖叫起来。

Discourse是一个严重依赖ajax的论坛程序,但它必须让google收录内容。它的解决方案是放弃hash结构,采用history api。
所谓history api,是指在不刷新页面的情况下,改变浏览器地址栏中显示的url(准确的说,就是改变网页的当前状态)。这是一个示例,您单击上面的按钮开始播放音乐。然后,点击下面的链接看看发生了什么?

地址栏的url变了,但音乐播放不中断!
history api的详细介绍超出了本文章的范围。简单来说,它的作用就是给浏览器的history对象添加一条记录。
window.history.pushstate(state object, title, url);
上面这行命令可以让地址栏中出现一个新的 URL。history对象的pushstate方法接受三个参数,new url为第三个参数,前两个参数可以为null。
window.history.pushstate(null, null, newurl);
目前主流浏览器都支持这种方式:chrome(26.0+)、firefox(20.0+)、ie(10.0+)、safari(5.1+),歌剧(12.1+)。
下面是robin ward的方法。
首先,将hash结构替换成history api,让每个hash符号变成一个正常路径的url,这样搜索引擎就会抓取每一个网页。
example.com/1 example.com/2 example.com/3
然后,定义一个javascript函数来处理ajax部分并根据URL抓取内容(假设使用jquery)。
function anchorclick(link) {
var linksplit = link.split('/').pop();
$.get('api/' + linksplit, function(data) {
$('#content').html(data);
});
}
然后定义鼠标的点击事件。
$('#container').on('click', 'a', function(e) {
window.history.pushstate(null, null, $(this).attr('href'));
anchorclick($(this).attr('href'));
e.preventdefault();
});
还要考虑用户点击浏览器的“前进/后退”按钮。这时候会触发history对象的popstate事件。
window.addeventlistener('popstate', function(e) {
anchorclick(location.pathname);
});
定义以上三段代码后,无需刷新页面即可显示正常路径url和ajax内容。
最后,设置服务器端。
因为没有使用 hashtag 结构,所以每个 URL 都是不同的请求。因此,服务器需要向所有这些请求返回具有以下结构的网页,以防止 404 错误。
... ...
如果你仔细看上面的代码,你会发现里面有一个 noscript 标签。这就是秘密。
我们将所有我们想要搜索引擎的内容放在了 noscript 标签中。在这种情况下,用户仍然可以在不刷新页面的情况下进行ajax操作,但是搜索引擎会收录每个页面的主要内容!
ajax抓取网页内容(越来越多的网站采用“单页应用”的解决办法)
网站优化 • 优采云 发表了文章 • 0 个评论 • 47 次浏览 • 2021-12-21 01:08
越来越多的网站开始采用“单页应用”。
整个网站只有一个网页,它使用Ajax技术根据用户输入加载不同的内容。
这种方式的优点是用户体验好,节省流量。缺点是搜索引擎无法抓取 AJAX 内容。例如,您有一个 网站。
用户可以通过具有哈希结构的 URL 看到不同的内容。
# 1 # 2 # 3 但是,搜索引擎只会抓取,忽略哈希符号,因此无法索引内容。
为了解决这个问题,谷歌提出了“感叹号”的结构。
#!1 当谷歌发现这样一个网址时,它会自动抓取另一个网址:
只要你把AJAX内容放到这个网站上,Google就会收录。但问题是'感叹号'非常丑陋和笨重。Twitter 过去使用这种结构,它把
变成
#!/Ruan Yifei 结果,用户抱怨连连,只用了半年时间就废了。
那么,有没有什么方法可以让搜索引擎在抓取 AJAX 内容的同时保持直观的 URL 呢?
一直觉得做不到,直到前两天看到《话语》创始人之一罗宾·沃德的解决方案,我才忍不住尖叫起来。
Discourse 是一个严重依赖 Ajax 的论坛程序,但 Google 必须收录内容。解决方案是放弃hashtag结构,采用历史API。
所谓history API,就是在不刷新页面的情况下,改变浏览器地址栏中显示的URL(准确的说,就是改变网页的当前状态)。这是一个例子。您单击上面的按钮开始播放音乐。然后,单击下面的链接,看看发生了什么。
地址栏中的网址已更改,但音乐播放并未中断!
对历史 API 的详细介绍超出了本文的范围。简单的说,它的作用就是给浏览器的History对象添加一条记录。
window.history.pushState(状态对象、标题、URL);上面的命令可以在地址栏中显示一个新的 URL。History对象的pushState方法接受三个参数,新的URL为第三个参数,前两个参数可以为空。
window.history.pushState(null, null, new URl); 目前主流浏览器都支持这种方式:Chrome(26.0), Firefox(20.0), IE(10.0), Safari(5.1), Opera(12.1).
以下是Robin Ward 的方法。
首先用History API替换hash结构,让每一个hash都变成一个正常路径的URL,这样搜索引擎就会抓取每一个网页。
然后, ///3 定义一个 JavaScript 函数来处理 Ajax 并根据 URL 抓取内容(假设使用了 jQuery)。
函数 anchorClick(link){ var linkSplit=link. 分裂('/')。流行音乐(); $.get('api/' linkSplit, function (data){$('#content').html(data);});} 然后定义鼠标点击事件。
$('#container')。on('click',' a',function(e){ window.history.push state(null,null,$(this)).attr(' href'); anchorClick($(this).attr(' href '); e.PreventDefault();}); 还要考虑用户点击了浏览器的“前进/后退”按钮,此时触发了历史对象的popstate事件。
窗户。addeventlistener('pop state', function (e){ anchorClick(location .pathname);}); 定义以上三个代码后,无需刷新页面即可显示正常路径URL和AJAX内容。
最后,设置服务器端。
因为没有使用哈希结构,所以每个 URL 都是不同的请求。因此,服务器需要为所有这些请求返回一个具有以下结构的网页,以防止 404 错误。
htmlbody section id='container'/section noscript./noscript/body/html 仔细看上面的代码,你会发现里面有一个no script标签,这就是秘诀。
我们将搜索引擎中收录的所有内容都放在 noscript 标签中。这样,用户仍然可以在不刷新页面的情况下进行AJAX操作,但是搜索引擎会记录每个页面的主要内容! 查看全部
ajax抓取网页内容(越来越多的网站采用“单页应用”的解决办法)
越来越多的网站开始采用“单页应用”。
整个网站只有一个网页,它使用Ajax技术根据用户输入加载不同的内容。

这种方式的优点是用户体验好,节省流量。缺点是搜索引擎无法抓取 AJAX 内容。例如,您有一个 网站。
用户可以通过具有哈希结构的 URL 看到不同的内容。
# 1 # 2 # 3 但是,搜索引擎只会抓取,忽略哈希符号,因此无法索引内容。
为了解决这个问题,谷歌提出了“感叹号”的结构。
#!1 当谷歌发现这样一个网址时,它会自动抓取另一个网址:
只要你把AJAX内容放到这个网站上,Google就会收录。但问题是'感叹号'非常丑陋和笨重。Twitter 过去使用这种结构,它把
变成
#!/Ruan Yifei 结果,用户抱怨连连,只用了半年时间就废了。
那么,有没有什么方法可以让搜索引擎在抓取 AJAX 内容的同时保持直观的 URL 呢?
一直觉得做不到,直到前两天看到《话语》创始人之一罗宾·沃德的解决方案,我才忍不住尖叫起来。

Discourse 是一个严重依赖 Ajax 的论坛程序,但 Google 必须收录内容。解决方案是放弃hashtag结构,采用历史API。
所谓history API,就是在不刷新页面的情况下,改变浏览器地址栏中显示的URL(准确的说,就是改变网页的当前状态)。这是一个例子。您单击上面的按钮开始播放音乐。然后,单击下面的链接,看看发生了什么。

地址栏中的网址已更改,但音乐播放并未中断!
对历史 API 的详细介绍超出了本文的范围。简单的说,它的作用就是给浏览器的History对象添加一条记录。
window.history.pushState(状态对象、标题、URL);上面的命令可以在地址栏中显示一个新的 URL。History对象的pushState方法接受三个参数,新的URL为第三个参数,前两个参数可以为空。
window.history.pushState(null, null, new URl); 目前主流浏览器都支持这种方式:Chrome(26.0), Firefox(20.0), IE(10.0), Safari(5.1), Opera(12.1).
以下是Robin Ward 的方法。
首先用History API替换hash结构,让每一个hash都变成一个正常路径的URL,这样搜索引擎就会抓取每一个网页。
然后, ///3 定义一个 JavaScript 函数来处理 Ajax 并根据 URL 抓取内容(假设使用了 jQuery)。
函数 anchorClick(link){ var linkSplit=link. 分裂('/')。流行音乐(); $.get('api/' linkSplit, function (data){$('#content').html(data);});} 然后定义鼠标点击事件。
$('#container')。on('click',' a',function(e){ window.history.push state(null,null,$(this)).attr(' href'); anchorClick($(this).attr(' href '); e.PreventDefault();}); 还要考虑用户点击了浏览器的“前进/后退”按钮,此时触发了历史对象的popstate事件。
窗户。addeventlistener('pop state', function (e){ anchorClick(location .pathname);}); 定义以上三个代码后,无需刷新页面即可显示正常路径URL和AJAX内容。
最后,设置服务器端。
因为没有使用哈希结构,所以每个 URL 都是不同的请求。因此,服务器需要为所有这些请求返回一个具有以下结构的网页,以防止 404 错误。
htmlbody section id='container'/section noscript./noscript/body/html 仔细看上面的代码,你会发现里面有一个no script标签,这就是秘诀。
我们将搜索引擎中收录的所有内容都放在 noscript 标签中。这样,用户仍然可以在不刷新页面的情况下进行AJAX操作,但是搜索引擎会记录每个页面的主要内容!
ajax抓取网页内容(抓ajax异步内容页面和抓普通的页面区别。 )
网站优化 • 优采云 发表了文章 • 0 个评论 • 54 次浏览 • 2021-12-20 04:14
)
其实抓取ajax异步内容页面和抓取普通页面没有太大区别。 Ajax 只是发出一个异步 http 请求。用类似firebug的工具,找到请求的后端服务url和传参值,然后抓取url传参即可。
使用 Firebug 的网络工具
如果抓取一个页面,内容中没有显示的数据是一堆JS代码。
代码
$cookie_file=tempnam('./temp','cookie');
$ch = curl_init();
$url1 = "http://www.cdut.edu.cn/default.html";
curl_setopt($ch,CURLOPT_URL,$url1);
curl_setopt($ch,CURLOPT_HTTP_VERSION,CURL_HTTP_VERSION_1_1);
curl_setopt($ch,CURLOPT_HEADER,0);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch,CURLOPT_FOLLOWLOCATION,1);
curl_setopt($ch, CURLOPT_ENCODING ,'gzip'); //加入gzip解析
//设置连接结束后保存cookie信息的文件
curl_setopt($ch,CURLOPT_COOKIEJAR,$cookie_file);
$content=curl_exec($ch);
curl_close($ch);
$ch3 = curl_init();
$url3 = "http://www.cdut.edu.cn/xww/dwr ... 3B%3B
$curlPost = "callCount=1&page=/xww/type/1000020118.html&httpSessionId=12A9B726E6A2D4D3B09DE7952B2F282C&scriptSessionId=295315B4B4141B09DA888D3A3ADB8FAA658&c0-scriptName=portalAjax&c0-methodName=getNewsXml&c0-id=0&c0-param0=string:10000201&c0-param1=string:1000020118&c0-param2=string:news_&c0-param3=number:5969&c0-param4=number:1&c0-param5=null:null&c0-param6=null:null&batchId=0";
curl_setopt($ch3,CURLOPT_URL,$url3);
curl_setopt($ch3,CURLOPT_POST,1);
curl_setopt($ch3,CURLOPT_POSTFIELDS,$curlPost);
//设置连接结束后保存cookie信息的文件
curl_setopt($ch3,CURLOPT_COOKIEFILE,$cookie_file);
$content1=curl_exec($ch3);
curl_close($ch3); 查看全部
ajax抓取网页内容(抓ajax异步内容页面和抓普通的页面区别。
)
其实抓取ajax异步内容页面和抓取普通页面没有太大区别。 Ajax 只是发出一个异步 http 请求。用类似firebug的工具,找到请求的后端服务url和传参值,然后抓取url传参即可。
使用 Firebug 的网络工具

如果抓取一个页面,内容中没有显示的数据是一堆JS代码。

代码
$cookie_file=tempnam('./temp','cookie');
$ch = curl_init();
$url1 = "http://www.cdut.edu.cn/default.html";
curl_setopt($ch,CURLOPT_URL,$url1);
curl_setopt($ch,CURLOPT_HTTP_VERSION,CURL_HTTP_VERSION_1_1);
curl_setopt($ch,CURLOPT_HEADER,0);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch,CURLOPT_FOLLOWLOCATION,1);
curl_setopt($ch, CURLOPT_ENCODING ,'gzip'); //加入gzip解析
//设置连接结束后保存cookie信息的文件
curl_setopt($ch,CURLOPT_COOKIEJAR,$cookie_file);
$content=curl_exec($ch);
curl_close($ch);
$ch3 = curl_init();
$url3 = "http://www.cdut.edu.cn/xww/dwr ... 3B%3B
$curlPost = "callCount=1&page=/xww/type/1000020118.html&httpSessionId=12A9B726E6A2D4D3B09DE7952B2F282C&scriptSessionId=295315B4B4141B09DA888D3A3ADB8FAA658&c0-scriptName=portalAjax&c0-methodName=getNewsXml&c0-id=0&c0-param0=string:10000201&c0-param1=string:1000020118&c0-param2=string:news_&c0-param3=number:5969&c0-param4=number:1&c0-param5=null:null&c0-param6=null:null&batchId=0";
curl_setopt($ch3,CURLOPT_URL,$url3);
curl_setopt($ch3,CURLOPT_POST,1);
curl_setopt($ch3,CURLOPT_POSTFIELDS,$curlPost);
//设置连接结束后保存cookie信息的文件
curl_setopt($ch3,CURLOPT_COOKIEFILE,$cookie_file);
$content1=curl_exec($ch3);
curl_close($ch3);
ajax抓取网页内容(百度网络蜘蛛更有效识别页面文字内容并建议涉及开发网页)
网站优化 • 优采云 发表了文章 • 0 个评论 • 60 次浏览 • 2021-12-18 16:07
A 网站只有百度把尽可能多的页面收录进入索引库,才能获得更好的权重,进而促进网站获得更好的曝光率,所以百度网络蜘蛛可以有效地捕捉 抓取页面是关键词排名的第一步,其他搜索引擎一般也是这样做的。百度的收录网站页面的机制是通过一个叫Baiduspider的蜘蛛程序自动抓取互联网上的网页,处理后存入索引库。目前百度蜘蛛只能读取文本内容。Flash、图片、视频、JavaScript等非文本内容暂时无法处理。因此,很多公司网站为了美观的界面,把文字和图片放在flash里,百度却认不出来。
1、 尽量使用有效的文字代替flash、图片、Javascript等来展示网页中的重要内容或链接。如果为了页面美观需要使用图片,建议图片必须设置有效的关键词 Alt属性,图片周围必须有可以描述图片的文字,最好有关键字。
2、 随着网络技术和带宽的进步,有时需要在网页中安排动画、视频、音频等多媒体元素,以更好地说明产品说明、公司的生产实力、公司的技术水平,获得了网友的高度信任。,为了更好的服务模板客户,网站将使用音频、视频等多媒体元素。建议在网页的这部分尽可能同时提供文字说明。文字说明可以使用必要的技术,不要在网页上显示。
3、 Ajax 和其他搜索引擎无法识别的技术只在需要用户交互的地方使用,而您希望搜索引擎“看到”的导航和文本内容不会放入 Ajax。尽量少用frame和iframe结构,通过iframe显示的内容可能会被百度丢弃。 查看全部
ajax抓取网页内容(百度网络蜘蛛更有效识别页面文字内容并建议涉及开发网页)
A 网站只有百度把尽可能多的页面收录进入索引库,才能获得更好的权重,进而促进网站获得更好的曝光率,所以百度网络蜘蛛可以有效地捕捉 抓取页面是关键词排名的第一步,其他搜索引擎一般也是这样做的。百度的收录网站页面的机制是通过一个叫Baiduspider的蜘蛛程序自动抓取互联网上的网页,处理后存入索引库。目前百度蜘蛛只能读取文本内容。Flash、图片、视频、JavaScript等非文本内容暂时无法处理。因此,很多公司网站为了美观的界面,把文字和图片放在flash里,百度却认不出来。
1、 尽量使用有效的文字代替flash、图片、Javascript等来展示网页中的重要内容或链接。如果为了页面美观需要使用图片,建议图片必须设置有效的关键词 Alt属性,图片周围必须有可以描述图片的文字,最好有关键字。
2、 随着网络技术和带宽的进步,有时需要在网页中安排动画、视频、音频等多媒体元素,以更好地说明产品说明、公司的生产实力、公司的技术水平,获得了网友的高度信任。,为了更好的服务模板客户,网站将使用音频、视频等多媒体元素。建议在网页的这部分尽可能同时提供文字说明。文字说明可以使用必要的技术,不要在网页上显示。
3、 Ajax 和其他搜索引擎无法识别的技术只在需要用户交互的地方使用,而您希望搜索引擎“看到”的导航和文本内容不会放入 Ajax。尽量少用frame和iframe结构,通过iframe显示的内容可能会被百度丢弃。
ajax抓取网页内容(ajax都搜不到我们的页面你以为你尽力了吗)
网站优化 • 优采云 发表了文章 • 0 个评论 • 38 次浏览 • 2021-12-18 04:04
说到Ajax的缺点,很多人会认为不利于SEO的一面。大搜索时代,搜索引擎找不到我们的页面,你肯定会有淡淡的忧伤。你认为你尽力了,显然没有,那我们该怎么办?
一、先回顾一下ajax的一些不足,
①破坏浏览器的后退按钮,使其无法运行;
②对搜索引擎不友好;
③不支持跨域请求;
④ ajax脚本语言嵌入在HTML页面中,可以通过查看源代码或firebug等工具直接查看,不利于项目代码的保密。
第二个提到了,对搜索引擎不友好。这意味着什么?这么说吧,越来越多的网站开始采用“单页结构”。整个网站只有一个网页,使用ajax技术根据用户输入加载不同的内容。
这种方式的优点是用户体验好,节省流量。缺点是ajax内容无法被搜索引擎抓取。因为搜索引擎会爬取整个页面的内容,这样统计数据才能达到搜索的目的,而且Ajax请求的文件在用户操作之前放在服务器上,无论搜索引擎有多强大,信息或无法搜索资源。.
因此,缺点是显而易见的。之前也想过这个问题,但是没有很好的解决办法。直到看到这个文章,忍不住拍案叫绝,分享出来供大家参考:
how_to_make_search_engines_find_ajax_content
二、如何解决
1. 将hashtag结构替换为History API,让每个hashtag变成正常路径的URL,这样搜索引擎就会抓取每一个网页。
1<br />2<br />3<br />
example.com/1<br />example.com/2<br />example.com/3<br />
2.定义一个 JavaScript 函数来处理 Ajax 部分并根据 URL 抓取内容(假设使用 jQuery)。
1<br />2<br />3<br />4<br />5<br />6<br />
function anchorClick(link) {<br /> var linkSplit = link.split('/').pop();<br /> $.get('api/' + linkSplit, function(data) {<br /> $('#content').html(data);<br /> });<br />}<br />
然后定义鼠标的点击事件。
1<br />2<br />3<br />4<br />5<br />
$('#container').on('click', 'a', function(e) {<br /> window.history.pushState(null, null, $(this).attr('href'));<br /> anchorClick($(this).attr('href'));<br /> e.preventDefault();<br />});<br />
还要考虑用户单击浏览器的“前进/后退”按钮。这时候会触发History对象的popstate事件。
1<br />2<br />3<br />
window.addEventListener('popstate', function(e) {<br /> anchorClick(location.pathname);<br />});<br />
定义以上三段代码后,无需刷新页面即可显示正常路径URL和AJAX内容。
3.设置服务器端。
因为没有使用 hashtag 结构,所以每个 URL 都是不同的请求。因此,服务器需要向所有这些请求返回具有以下结构的网页,以防止 404 错误。
1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />
<br /> <br /> <br /> <br /> ... ...<br /> <br /> <br /><br />
总之,意思很明确。就是用js把url拼出来写进地址栏,这样搜索引擎当然可以抓取页面的内容。 查看全部
ajax抓取网页内容(ajax都搜不到我们的页面你以为你尽力了吗)
说到Ajax的缺点,很多人会认为不利于SEO的一面。大搜索时代,搜索引擎找不到我们的页面,你肯定会有淡淡的忧伤。你认为你尽力了,显然没有,那我们该怎么办?
一、先回顾一下ajax的一些不足,
①破坏浏览器的后退按钮,使其无法运行;
②对搜索引擎不友好;
③不支持跨域请求;
④ ajax脚本语言嵌入在HTML页面中,可以通过查看源代码或firebug等工具直接查看,不利于项目代码的保密。
第二个提到了,对搜索引擎不友好。这意味着什么?这么说吧,越来越多的网站开始采用“单页结构”。整个网站只有一个网页,使用ajax技术根据用户输入加载不同的内容。
这种方式的优点是用户体验好,节省流量。缺点是ajax内容无法被搜索引擎抓取。因为搜索引擎会爬取整个页面的内容,这样统计数据才能达到搜索的目的,而且Ajax请求的文件在用户操作之前放在服务器上,无论搜索引擎有多强大,信息或无法搜索资源。.
因此,缺点是显而易见的。之前也想过这个问题,但是没有很好的解决办法。直到看到这个文章,忍不住拍案叫绝,分享出来供大家参考:
how_to_make_search_engines_find_ajax_content
二、如何解决
1. 将hashtag结构替换为History API,让每个hashtag变成正常路径的URL,这样搜索引擎就会抓取每一个网页。
1<br />2<br />3<br />
example.com/1<br />example.com/2<br />example.com/3<br />
2.定义一个 JavaScript 函数来处理 Ajax 部分并根据 URL 抓取内容(假设使用 jQuery)。
1<br />2<br />3<br />4<br />5<br />6<br />
function anchorClick(link) {<br /> var linkSplit = link.split('/').pop();<br /> $.get('api/' + linkSplit, function(data) {<br /> $('#content').html(data);<br /> });<br />}<br />
然后定义鼠标的点击事件。
1<br />2<br />3<br />4<br />5<br />
$('#container').on('click', 'a', function(e) {<br /> window.history.pushState(null, null, $(this).attr('href'));<br /> anchorClick($(this).attr('href'));<br /> e.preventDefault();<br />});<br />
还要考虑用户单击浏览器的“前进/后退”按钮。这时候会触发History对象的popstate事件。
1<br />2<br />3<br />
window.addEventListener('popstate', function(e) {<br /> anchorClick(location.pathname);<br />});<br />
定义以上三段代码后,无需刷新页面即可显示正常路径URL和AJAX内容。
3.设置服务器端。
因为没有使用 hashtag 结构,所以每个 URL 都是不同的请求。因此,服务器需要向所有这些请求返回具有以下结构的网页,以防止 404 错误。
1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />
<br /> <br /> <br /> <br /> ... ...<br /> <br /> <br /><br />
总之,意思很明确。就是用js把url拼出来写进地址栏,这样搜索引擎当然可以抓取页面的内容。
ajax抓取网页内容(常见的反爬机制及处理方式-苏州安嘉网络)
网站优化 • 优采云 发表了文章 • 0 个评论 • 35 次浏览 • 2021-12-14 19:24
常见的防爬机构及处理方法
1、Headers 反爬虫:Cookie、Referer、User-Agent
解决方法:通过F12获取headers,传递给requests.get()方法
2、IP限制:网站根据IP地址访问频率反爬,短时间内IP访问
解决方案:
1、 构建自己的IP代理池,每次访问随机选择代理,频繁更新代理池
2、购买开放代理或私有代理IP
3、降低爬行速度
3、User-Agent 限制:类似于 IP 限制
解决方案:构建自己的User-Agent池,每次访问随机选择
5、查询参数或表单数据的认证(salt,sign)
解决方法:找到JS文件,分析JS处理方式,用Python同样处理
6、处理响应内容
解决方法:打印查看响应内容,使用xpath或者正则处理
python中标题和表单数据的常规处理
1、pycharm 进入方法:Ctrl + r,选择Regex
2、处理标头和表单数据
(.*): (.*)
"1":"1":"2",
3、点击全部替换
民政部网站数据采集
目标:抓取中华人民共和国县级以上最新行政区划代码
网址:-民政数据-行政部门代码
实施步骤
1、民政数据提取最新行政区划代码链接网站
最新在上,命名格式:X,2019,中华人民共和国县及以上行政区划代码
import requests
from lxml import etree
import re
url = 'http://www.mca.gov.cn/article/sj/xzqh/2019/'
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36'}
html = requests.get(url, headers=headers).text
parse_html = etree.HTML(html)
article_list = parse_html.xpath('//a[@class="artitlelist"]')
for article in article_list:
title = article.xpath('./@title')[0]
# 正则匹配title中包含这个字符串的链接
if title.endswith('代码'):
# 获取到第1个就停止即可,第1个永远是最新的链接
two_link = 'http://www.mca.gov.cn' + article.xpath('./@href')[0]
print(two_link)
break
2、 从二级页面链接中提取真实链接(反爬-响应在网页内容中嵌入JS,指向新的网页链接)
向二级页面链接发送请求获取响应内容,查看嵌入的JS代码
定期提取真实二级页面链接
# 爬取二级“假”链接
two_html = requests.get(two_link, headers=headers).text
# 从二级页面的响应中提取真实的链接(此处为JS动态加载跳转的地址)
new_two_link = re.findall(r'window.location.href="(.*?)" rel="external nofollow" rel="external nofollow" ', two_html, re.S)[0]
3、在数据库表中查询该链接是否被爬取过,构建增量爬虫
在数据库中创建一个版本表来存储爬取的链接
每次执行程序都会记录版本表,查看是否被爬取过
cursor.execute('select * from version')
result = self.cursor.fetchall()
if result:
if result[-1][0] == two_link:
print('已是最新')
else:
# 有更新,开始抓取
# 将链接再重新插入version表记录
4、代码实现
import requests
from lxml import etree
import re
import pymysql
class GovementSpider(object):
def __init__(self):
self.url = 'http://www.mca.gov.cn/article/sj/xzqh/2019/'
self.headers = {'User-Agent': 'Mozilla/5.0'}
# 创建2个对象
self.db = pymysql.connect('127.0.0.1', 'root', '123456', 'govdb', charset='utf8')
self.cursor = self.db.cursor()
# 获取假链接
def get_false_link(self):
html = requests.get(url=self.url, headers=self.headers).text
# 此处隐藏了真实的二级页面的url链接,真实的在假的响应网页中,通过js脚本生成,
# 假的链接在网页中可以访问,但是爬取到的内容却不是我们想要的
parse_html = etree.HTML(html)
a_list = parse_html.xpath('//a[@class="artitlelist"]')
for a in a_list:
# get()方法:获取某个属性的值
title = a.get('title')
if title.endswith('代码'):
# 获取到第1个就停止即可,第1个永远是最新的链接
false_link = 'http://www.mca.gov.cn' + a.get('href')
print("二级“假”链接的网址为", false_link)
break
# 提取真链接
self.incr_spider(false_link)
# 增量爬取函数
def incr_spider(self, false_link):
self.cursor.execute('select url from version where url=%s', [false_link])
# fetchall: (('http://xxxx.html',),)
result = self.cursor.fetchall()
# not result:代表数据库version表中无数据
if not result:
self.get_true_link(false_link)
# 可选操作: 数据库version表中只保留最新1条数据
self.cursor.execute("delete from version")
# 把爬取后的url插入到version表中
self.cursor.execute('insert into version values(%s)', [false_link])
self.db.commit()
else:
print('数据已是最新,无须爬取')
# 获取真链接
def get_true_link(self, false_link):
# 先获取假链接的响应,然后根据响应获取真链接
html = requests.get(url=false_link, headers=self.headers).text
# 从二级页面的响应中提取真实的链接(此处为JS动态加载跳转的地址)
re_bds = r'window.location.href="(.*?)" rel="external nofollow" rel="external nofollow" '
pattern = re.compile(re_bds, re.S)
true_link = pattern.findall(html)[0]
self.save_data(true_link) # 提取真链接的数据
# 用xpath直接提取数据
def save_data(self, true_link):
html = requests.get(url=true_link, headers=self.headers).text
# 基准xpath,提取每个信息的节点列表对象
parse_html = etree.HTML(html)
tr_list = parse_html.xpath('//tr[@height="19"]')
for tr in tr_list:
code = tr.xpath('./td[2]/text()')[0].strip() # 行政区划代码
name = tr.xpath('./td[3]/text()')[0].strip() # 单位名称
print(name, code)
# 主函数
def main(self):
self.get_false_link()
if __name__ == '__main__':
spider = GovementSpider()
spider.main()
动态加载数据捕获-Ajax
特征
右键->查看没有具体数据的网页源代码
滚动鼠标滚轮或其他动作时加载
抓
F12打开控制台,选择XHR异步加载数据包,找到page action抓取网络数据包
通过XHR-->Header-->General-->Request URL获取json文件的URL地址
通过XHR-->Header-->查询字符串参数
豆瓣电影数据采集案例
目标
地址:豆瓣电影排行榜-故事
type_name=%E5%89%A7%E6%83%85&type=11&interval_id=100:90&action=
目标:抓取电影名称、电影评级
F12 数据包捕获 (XHR)
1、请求 URL(基本 URL 地址):
2、Query String Paramaters(查询参数)
# 查询参数如下:
type: 13 # 电影类型
interval_id: 100:90
action: '[{},{},{}]'
start: 0 # 每次加载电影的起始索引值
limit: 20 # 每次加载的电影数量
json文件位于以下地址:
基本 URL 地址 + 查询参数
''+'type=11&interval_id=100%3A90&action=&start=20&limit=20'
代码
import requests
import time
from fake_useragent import UserAgent
class DoubanSpider(object):
def __init__(self):
self.base_url = 'https://movie.douban.com/j/chart/top_list?'
self.i = 0
def get_html(self, params):
headers = {'User-Agent': UserAgent().random}
res = requests.get(url=self.base_url, params=params, headers=headers)
res.encoding = 'utf-8'
html = res.json() # 将json格式的字符串转为python数据类型
self.parse_html(html) # 直接调用解析函数
def parse_html(self, html):
# html: [{电影1信息},{电影2信息},{}]
item = {}
for one in html:
item['name'] = one['title'] # 电影名
item['score'] = one['score'] # 评分
item['time'] = one['release_date'] # 打印测试
# 打印显示
print(item)
self.i += 1
# 获取电影总数
def get_total(self, typ):
# 异步动态加载的数据 都可以在XHR数据抓包
url = 'https://movie.douban.com/j/chart/top_list_count?type={}&interval_id=100%3A90'.format(typ)
ua = UserAgent()
html = requests.get(url=url, headers={'User-Agent': ua.random}).json()
total = html['total']
return total
def main(self):
typ = input('请输入电影类型(剧情|喜剧|动作):')
typ_dict = {'剧情': '11', '喜剧': '24', '动作': '5'}
typ = typ_dict[typ]
total = self.get_total(typ) # 获取该类型电影总数量
for page in range(0, int(total), 20):
params = {
'type': typ,
'interval_id': '100:90',
'action': '',
'start': str(page),
'limit': '20'}
self.get_html(params)
time.sleep(1)
print('爬取的电影的数量:', self.i)
if __name__ == '__main__':
spider = DoubanSpider()
spider.main()
腾讯招聘数据抓取(Ajax)
确定 URL 地址和目标
网址:百度搜索腾讯招聘-查看职位
目标:职位名称、工作职责、工作要求
需求与分析
通过查看网页源代码,我们知道所有需要的数据都是Ajax动态加载的
通过F12捕获网络数据包进行分析
一级页面爬取数据:职位
在二级页面上抓取数据:工作职责、工作要求
一级页面的json地址(pageIndex在变化,时间戳不检查)
{}&pageSize=10&language=zh-cn&area=cn
二级页面地址(postId在变化,可以在一级页面获取)
{}&language=zh-cn
用户代理.py文件
ua_list = [
'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.163 Safari/535.1',
'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0) Gecko/20100101 Firefox/6.0',
'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; InfoPath.3)',
]
import time
import json
import random
import requests
from useragents import ua_list
class TencentSpider(object):
def __init__(self):
self.one_url = 'https://careers.tencent.com/tencentcareer/api/post/Query?timestamp=1563912271089&countryId=&cityId=&bgIds=&productId=&categoryId=&parentCategoryId=&attrId=&keyword=&pageIndex={}&pageSize=10&language=zh-cn&area=cn'
self.two_url = 'https://careers.tencent.com/tencentcareer/api/post/ByPostId?timestamp=1563912374645&postId={}&language=zh-cn'
self.f = open('tencent.json', 'a') # 打开文件
self.item_list = [] # 存放抓取的item字典数据
# 获取响应内容函数
def get_page(self, url):
headers = {'User-Agent': random.choice(ua_list)}
html = requests.get(url=url, headers=headers).text
html = json.loads(html) # json格式字符串转为Python数据类型
return html
# 主线函数: 获取所有数据
def parse_page(self, one_url):
html = self.get_page(one_url)
item = {}
for job in html['Data']['Posts']:
item['name'] = job['RecruitPostName'] # 名称
post_id = job['PostId'] # postId,拿postid为了拼接二级页面地址
# 拼接二级地址,获取职责和要求
two_url = self.two_url.format(post_id)
item['duty'], item['require'] = self.parse_two_page(two_url)
print(item)
self.item_list.append(item) # 添加到大列表中
# 解析二级页面函数
def parse_two_page(self, two_url):
html = self.get_page(two_url)
duty = html['Data']['Responsibility'] # 工作责任
duty = duty.replace('\r\n', '').replace('\n', '') # 去掉换行
require = html['Data']['Requirement'] # 工作要求
require = require.replace('\r\n', '').replace('\n', '') # 去掉换行
return duty, require
# 获取总页数
def get_numbers(self):
url = self.one_url.format(1)
html = self.get_page(url)
numbers = int(html['Data']['Count']) // 10 + 1 # 每页有10个推荐
return numbers
def main(self):
number = self.get_numbers()
for page in range(1, 3):
one_url = self.one_url.format(page)
self.parse_page(one_url)
# 保存到本地json文件:json.dump
json.dump(self.item_list, self.f, ensure_ascii=False)
self.f.close()
if __name__ == '__main__':
start = time.time()
spider = TencentSpider()
spider.main()
end = time.time()
print('执行时间:%.2f' % (end - start))
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持面圈教程。 查看全部
ajax抓取网页内容(常见的反爬机制及处理方式-苏州安嘉网络)
常见的防爬机构及处理方法
1、Headers 反爬虫:Cookie、Referer、User-Agent
解决方法:通过F12获取headers,传递给requests.get()方法
2、IP限制:网站根据IP地址访问频率反爬,短时间内IP访问
解决方案:
1、 构建自己的IP代理池,每次访问随机选择代理,频繁更新代理池
2、购买开放代理或私有代理IP
3、降低爬行速度
3、User-Agent 限制:类似于 IP 限制
解决方案:构建自己的User-Agent池,每次访问随机选择
5、查询参数或表单数据的认证(salt,sign)
解决方法:找到JS文件,分析JS处理方式,用Python同样处理
6、处理响应内容
解决方法:打印查看响应内容,使用xpath或者正则处理
python中标题和表单数据的常规处理
1、pycharm 进入方法:Ctrl + r,选择Regex
2、处理标头和表单数据
(.*): (.*)
"1":"1":"2",
3、点击全部替换
民政部网站数据采集
目标:抓取中华人民共和国县级以上最新行政区划代码
网址:-民政数据-行政部门代码
实施步骤
1、民政数据提取最新行政区划代码链接网站
最新在上,命名格式:X,2019,中华人民共和国县及以上行政区划代码
import requests
from lxml import etree
import re
url = 'http://www.mca.gov.cn/article/sj/xzqh/2019/'
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36'}
html = requests.get(url, headers=headers).text
parse_html = etree.HTML(html)
article_list = parse_html.xpath('//a[@class="artitlelist"]')
for article in article_list:
title = article.xpath('./@title')[0]
# 正则匹配title中包含这个字符串的链接
if title.endswith('代码'):
# 获取到第1个就停止即可,第1个永远是最新的链接
two_link = 'http://www.mca.gov.cn' + article.xpath('./@href')[0]
print(two_link)
break
2、 从二级页面链接中提取真实链接(反爬-响应在网页内容中嵌入JS,指向新的网页链接)
向二级页面链接发送请求获取响应内容,查看嵌入的JS代码
定期提取真实二级页面链接
# 爬取二级“假”链接
two_html = requests.get(two_link, headers=headers).text
# 从二级页面的响应中提取真实的链接(此处为JS动态加载跳转的地址)
new_two_link = re.findall(r'window.location.href="(.*?)" rel="external nofollow" rel="external nofollow" ', two_html, re.S)[0]
3、在数据库表中查询该链接是否被爬取过,构建增量爬虫
在数据库中创建一个版本表来存储爬取的链接
每次执行程序都会记录版本表,查看是否被爬取过
cursor.execute('select * from version')
result = self.cursor.fetchall()
if result:
if result[-1][0] == two_link:
print('已是最新')
else:
# 有更新,开始抓取
# 将链接再重新插入version表记录
4、代码实现
import requests
from lxml import etree
import re
import pymysql
class GovementSpider(object):
def __init__(self):
self.url = 'http://www.mca.gov.cn/article/sj/xzqh/2019/'
self.headers = {'User-Agent': 'Mozilla/5.0'}
# 创建2个对象
self.db = pymysql.connect('127.0.0.1', 'root', '123456', 'govdb', charset='utf8')
self.cursor = self.db.cursor()
# 获取假链接
def get_false_link(self):
html = requests.get(url=self.url, headers=self.headers).text
# 此处隐藏了真实的二级页面的url链接,真实的在假的响应网页中,通过js脚本生成,
# 假的链接在网页中可以访问,但是爬取到的内容却不是我们想要的
parse_html = etree.HTML(html)
a_list = parse_html.xpath('//a[@class="artitlelist"]')
for a in a_list:
# get()方法:获取某个属性的值
title = a.get('title')
if title.endswith('代码'):
# 获取到第1个就停止即可,第1个永远是最新的链接
false_link = 'http://www.mca.gov.cn' + a.get('href')
print("二级“假”链接的网址为", false_link)
break
# 提取真链接
self.incr_spider(false_link)
# 增量爬取函数
def incr_spider(self, false_link):
self.cursor.execute('select url from version where url=%s', [false_link])
# fetchall: (('http://xxxx.html',),)
result = self.cursor.fetchall()
# not result:代表数据库version表中无数据
if not result:
self.get_true_link(false_link)
# 可选操作: 数据库version表中只保留最新1条数据
self.cursor.execute("delete from version")
# 把爬取后的url插入到version表中
self.cursor.execute('insert into version values(%s)', [false_link])
self.db.commit()
else:
print('数据已是最新,无须爬取')
# 获取真链接
def get_true_link(self, false_link):
# 先获取假链接的响应,然后根据响应获取真链接
html = requests.get(url=false_link, headers=self.headers).text
# 从二级页面的响应中提取真实的链接(此处为JS动态加载跳转的地址)
re_bds = r'window.location.href="(.*?)" rel="external nofollow" rel="external nofollow" '
pattern = re.compile(re_bds, re.S)
true_link = pattern.findall(html)[0]
self.save_data(true_link) # 提取真链接的数据
# 用xpath直接提取数据
def save_data(self, true_link):
html = requests.get(url=true_link, headers=self.headers).text
# 基准xpath,提取每个信息的节点列表对象
parse_html = etree.HTML(html)
tr_list = parse_html.xpath('//tr[@height="19"]')
for tr in tr_list:
code = tr.xpath('./td[2]/text()')[0].strip() # 行政区划代码
name = tr.xpath('./td[3]/text()')[0].strip() # 单位名称
print(name, code)
# 主函数
def main(self):
self.get_false_link()
if __name__ == '__main__':
spider = GovementSpider()
spider.main()
动态加载数据捕获-Ajax
特征
右键->查看没有具体数据的网页源代码
滚动鼠标滚轮或其他动作时加载
抓
F12打开控制台,选择XHR异步加载数据包,找到page action抓取网络数据包
通过XHR-->Header-->General-->Request URL获取json文件的URL地址
通过XHR-->Header-->查询字符串参数
豆瓣电影数据采集案例
目标
地址:豆瓣电影排行榜-故事
type_name=%E5%89%A7%E6%83%85&type=11&interval_id=100:90&action=
目标:抓取电影名称、电影评级
F12 数据包捕获 (XHR)
1、请求 URL(基本 URL 地址):
2、Query String Paramaters(查询参数)
# 查询参数如下:
type: 13 # 电影类型
interval_id: 100:90
action: '[{},{},{}]'
start: 0 # 每次加载电影的起始索引值
limit: 20 # 每次加载的电影数量
json文件位于以下地址:
基本 URL 地址 + 查询参数
''+'type=11&interval_id=100%3A90&action=&start=20&limit=20'
代码
import requests
import time
from fake_useragent import UserAgent
class DoubanSpider(object):
def __init__(self):
self.base_url = 'https://movie.douban.com/j/chart/top_list?'
self.i = 0
def get_html(self, params):
headers = {'User-Agent': UserAgent().random}
res = requests.get(url=self.base_url, params=params, headers=headers)
res.encoding = 'utf-8'
html = res.json() # 将json格式的字符串转为python数据类型
self.parse_html(html) # 直接调用解析函数
def parse_html(self, html):
# html: [{电影1信息},{电影2信息},{}]
item = {}
for one in html:
item['name'] = one['title'] # 电影名
item['score'] = one['score'] # 评分
item['time'] = one['release_date'] # 打印测试
# 打印显示
print(item)
self.i += 1
# 获取电影总数
def get_total(self, typ):
# 异步动态加载的数据 都可以在XHR数据抓包
url = 'https://movie.douban.com/j/chart/top_list_count?type={}&interval_id=100%3A90'.format(typ)
ua = UserAgent()
html = requests.get(url=url, headers={'User-Agent': ua.random}).json()
total = html['total']
return total
def main(self):
typ = input('请输入电影类型(剧情|喜剧|动作):')
typ_dict = {'剧情': '11', '喜剧': '24', '动作': '5'}
typ = typ_dict[typ]
total = self.get_total(typ) # 获取该类型电影总数量
for page in range(0, int(total), 20):
params = {
'type': typ,
'interval_id': '100:90',
'action': '',
'start': str(page),
'limit': '20'}
self.get_html(params)
time.sleep(1)
print('爬取的电影的数量:', self.i)
if __name__ == '__main__':
spider = DoubanSpider()
spider.main()
腾讯招聘数据抓取(Ajax)
确定 URL 地址和目标
网址:百度搜索腾讯招聘-查看职位
目标:职位名称、工作职责、工作要求
需求与分析
通过查看网页源代码,我们知道所有需要的数据都是Ajax动态加载的
通过F12捕获网络数据包进行分析
一级页面爬取数据:职位
在二级页面上抓取数据:工作职责、工作要求
一级页面的json地址(pageIndex在变化,时间戳不检查)
{}&pageSize=10&language=zh-cn&area=cn
二级页面地址(postId在变化,可以在一级页面获取)
{}&language=zh-cn
用户代理.py文件
ua_list = [
'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.163 Safari/535.1',
'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0) Gecko/20100101 Firefox/6.0',
'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; InfoPath.3)',
]
import time
import json
import random
import requests
from useragents import ua_list
class TencentSpider(object):
def __init__(self):
self.one_url = 'https://careers.tencent.com/tencentcareer/api/post/Query?timestamp=1563912271089&countryId=&cityId=&bgIds=&productId=&categoryId=&parentCategoryId=&attrId=&keyword=&pageIndex={}&pageSize=10&language=zh-cn&area=cn'
self.two_url = 'https://careers.tencent.com/tencentcareer/api/post/ByPostId?timestamp=1563912374645&postId={}&language=zh-cn'
self.f = open('tencent.json', 'a') # 打开文件
self.item_list = [] # 存放抓取的item字典数据
# 获取响应内容函数
def get_page(self, url):
headers = {'User-Agent': random.choice(ua_list)}
html = requests.get(url=url, headers=headers).text
html = json.loads(html) # json格式字符串转为Python数据类型
return html
# 主线函数: 获取所有数据
def parse_page(self, one_url):
html = self.get_page(one_url)
item = {}
for job in html['Data']['Posts']:
item['name'] = job['RecruitPostName'] # 名称
post_id = job['PostId'] # postId,拿postid为了拼接二级页面地址
# 拼接二级地址,获取职责和要求
two_url = self.two_url.format(post_id)
item['duty'], item['require'] = self.parse_two_page(two_url)
print(item)
self.item_list.append(item) # 添加到大列表中
# 解析二级页面函数
def parse_two_page(self, two_url):
html = self.get_page(two_url)
duty = html['Data']['Responsibility'] # 工作责任
duty = duty.replace('\r\n', '').replace('\n', '') # 去掉换行
require = html['Data']['Requirement'] # 工作要求
require = require.replace('\r\n', '').replace('\n', '') # 去掉换行
return duty, require
# 获取总页数
def get_numbers(self):
url = self.one_url.format(1)
html = self.get_page(url)
numbers = int(html['Data']['Count']) // 10 + 1 # 每页有10个推荐
return numbers
def main(self):
number = self.get_numbers()
for page in range(1, 3):
one_url = self.one_url.format(page)
self.parse_page(one_url)
# 保存到本地json文件:json.dump
json.dump(self.item_list, self.f, ensure_ascii=False)
self.f.close()
if __name__ == '__main__':
start = time.time()
spider = TencentSpider()
spider.main()
end = time.time()
print('执行时间:%.2f' % (end - start))
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持面圈教程。
ajax抓取网页内容(思考的问题:怎么在一个网页的div中获取部分内容)
网站优化 • 优采云 发表了文章 • 0 个评论 • 53 次浏览 • 2021-12-13 15:17
需要考虑的问题:
如何在一个网页的div中嵌套另一个网页(不使用inclue,iframe和frame,不使用的原因,include只能嵌套静态网页,iframe影响网络爬虫,frame嵌套的网页无法获取父页面信息,不够灵活)如果您不想嵌套整个网页怎么办?(只是嵌套另一页内容的一部分)
答案(想法):
使用jquery的ajax函数或者load函数获取网页内容,从而实现嵌套网页(获取的网页内容为html字符串)如何从字符串中获取部分内容?
实践一:
index.html 页面(获取本页内容页的内容)
1
2
3
4 使用jquery的ajax函数获取网页内容
5
6 div{
7 display: block;
8 }
9
10
11
12
13
14
15
16
17
18 This is index.html;
19
20
21
22
23
24
25
26
27 /*
28 * 使用ajax方式获取网页内容(也可以使用load方式获取)
29 * */
30 //解决方案一
31 function GetPageContent1(url) {
32 $.ajax({
33 type: \'get\',
34 url: url,
35 async: true,
36 success: function(html) {
37 $("#content").html(html);
38 },
39 error: function(errorMsg){
40 alert(errorMsg);
41 }
42 })
43 }
44 //解决方案二
45 function GetPageContent2(url){
46 /* 想知道更多的load方法信息,请查阅jquery api */
47 $("#content").load(url);
48 }
49
查看代码
content.html 页面
1
2
3 内容页
4
5
6
7
8 This is Content Page;
9
10
11
12
查看代码
第一个问题可以在这里解决,点击获取完整的content.html页面内容
在参考jquery的load方法的时候可以发现load函数其实可以指定网页的内容
实践二:
改变index.html页面的ajax函数的url路径,获取content.html页面的div的id=container的内容
1
2
3
4 使用jquery的ajax函数获取网页内容
5
6 div{
7 display: block;
8 }
9
10
11
12
13
14
15
16
17
18 This is index.html;
19
20
21
22
23
24
25
26
27 /*
28 * 使用ajax方式获取网页内容(也可以使用load方式获取)
29 * */
30 //解决方案一
31 function GetPageContent1(url) {
32 $.ajax({
33 type: \'get\',
34 url: url + \' #container\',
35 async: true,
36 success: function(html) {
37 $("#content").html(html);
38 },
39 error: function(errorMsg){
40 alert(errorMsg);
41 }
42 })
43 }
44 //解决方案二
45 function GetPageContent2(url){
46 /* 想知道更多的load方法信息,请查阅jquery api */
47 $("#content").load(url + \' #container\');
48 }
49
查看代码
至此我们已经解决了文章开头提出的问题。. . . . . 但这是一个静态页面(html页面),是否适用?
答案是不。无论是ajax函数还是load函数获取的页面内容,都收录title标签和两个
这是ajax获取的内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 Welcome to Content Page!
17
18
查看代码
我们可以看到不仅获取到了div的内容,还多了两个div和一个title
我在网上查了一些资料。有人说使用 $(html).find("#container").html(); 可以解决,但是实践后还是不行。以下是我的最终解决方案
这是Test1.aspx页面,相当于之前的index.html(是我命名的错误,请见谅)
1
2
3 DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DT ... gt%3B
4
5
6
7
8
9 div{
10 display: block;
11 }
12
13
14
15
16
17
18
19
20
21
22 This is index.html;
23
24
25
26
27
28
29
30
31
32 /*
33 * 使用ajax方式获取网页内容(也可以使用load方式获取)
34 * */
35 //解决方案一
36 function GetPageContent1(url) {
37 $.ajax({
38 type: \'get\',
39 //url:直接使用url将会获取到整个网页的内容
40 //url + \' #container\':获取url网页中container容器内的内容
41 url: url + \' #container\',
42 async: true,
43 success: function (html) {
44 $("#content").html($(html).find(\'div[id=container]\').html());
45
46 //$("#content").html(html);
47 },
48 error: function(errorMsg) {
49 alert(errorMsg);
50 }
51 });
52 }
53 //解决方案二(缺点是content容器会被两次赋值,如不在加载完成之后的函数中进行数据处理,讲含有title、asp.net隐藏内容等标签)
54 function GetPageContent2(url) {
55 /* 想知道更多的load方法信息,请查阅jquery api */
56 $("#content").load(url + \' #container\', \'\', function (response, status, xhr) {
57 //response#是获取到的所有数据(未被截取),status#状态,成功或者失败,xhr#包含 XMLHttpRequest 对象
58 $("#content").html($(response).find(\'div[id=container]\').html());
59 });
60 }
61
62
查看代码
内容页面.aspx
1
2
3 DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DT ... gt%3B
4
5
6
7
8
9
10
11
12 Welcome to Content Page!
13
14
15
16
17
查看代码
注意:如果直接复制代码,请修改jquery文件路径
让我再补充一点,为什么不使用母版页
使用母版页,点击菜单会刷新整个网页,使用母版页会导致标签id改变。我想要实现的是点击菜单而不刷新页面 查看全部
ajax抓取网页内容(思考的问题:怎么在一个网页的div中获取部分内容)
需要考虑的问题:
如何在一个网页的div中嵌套另一个网页(不使用inclue,iframe和frame,不使用的原因,include只能嵌套静态网页,iframe影响网络爬虫,frame嵌套的网页无法获取父页面信息,不够灵活)如果您不想嵌套整个网页怎么办?(只是嵌套另一页内容的一部分)
答案(想法):
使用jquery的ajax函数或者load函数获取网页内容,从而实现嵌套网页(获取的网页内容为html字符串)如何从字符串中获取部分内容?
实践一:
index.html 页面(获取本页内容页的内容)
1
2
3
4 使用jquery的ajax函数获取网页内容
5
6 div{
7 display: block;
8 }
9
10
11
12
13
14
15
16
17
18 This is index.html;
19
20
21
22
23
24
25
26
27 /*
28 * 使用ajax方式获取网页内容(也可以使用load方式获取)
29 * */
30 //解决方案一
31 function GetPageContent1(url) {
32 $.ajax({
33 type: \'get\',
34 url: url,
35 async: true,
36 success: function(html) {
37 $("#content").html(html);
38 },
39 error: function(errorMsg){
40 alert(errorMsg);
41 }
42 })
43 }
44 //解决方案二
45 function GetPageContent2(url){
46 /* 想知道更多的load方法信息,请查阅jquery api */
47 $("#content").load(url);
48 }
49
查看代码
content.html 页面
1
2
3 内容页
4
5
6
7
8 This is Content Page;
9
10
11
12
查看代码
第一个问题可以在这里解决,点击获取完整的content.html页面内容
在参考jquery的load方法的时候可以发现load函数其实可以指定网页的内容
实践二:
改变index.html页面的ajax函数的url路径,获取content.html页面的div的id=container的内容
1
2
3
4 使用jquery的ajax函数获取网页内容
5
6 div{
7 display: block;
8 }
9
10
11
12
13
14
15
16
17
18 This is index.html;
19
20
21
22
23
24
25
26
27 /*
28 * 使用ajax方式获取网页内容(也可以使用load方式获取)
29 * */
30 //解决方案一
31 function GetPageContent1(url) {
32 $.ajax({
33 type: \'get\',
34 url: url + \' #container\',
35 async: true,
36 success: function(html) {
37 $("#content").html(html);
38 },
39 error: function(errorMsg){
40 alert(errorMsg);
41 }
42 })
43 }
44 //解决方案二
45 function GetPageContent2(url){
46 /* 想知道更多的load方法信息,请查阅jquery api */
47 $("#content").load(url + \' #container\');
48 }
49
查看代码
至此我们已经解决了文章开头提出的问题。. . . . . 但这是一个静态页面(html页面),是否适用?
答案是不。无论是ajax函数还是load函数获取的页面内容,都收录title标签和两个
这是ajax获取的内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 Welcome to Content Page!
17
18
查看代码
我们可以看到不仅获取到了div的内容,还多了两个div和一个title
我在网上查了一些资料。有人说使用 $(html).find("#container").html(); 可以解决,但是实践后还是不行。以下是我的最终解决方案
这是Test1.aspx页面,相当于之前的index.html(是我命名的错误,请见谅)
1
2
3 DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DT ... gt%3B
4
5
6
7
8
9 div{
10 display: block;
11 }
12
13
14
15
16
17
18
19
20
21
22 This is index.html;
23
24
25
26
27
28
29
30
31
32 /*
33 * 使用ajax方式获取网页内容(也可以使用load方式获取)
34 * */
35 //解决方案一
36 function GetPageContent1(url) {
37 $.ajax({
38 type: \'get\',
39 //url:直接使用url将会获取到整个网页的内容
40 //url + \' #container\':获取url网页中container容器内的内容
41 url: url + \' #container\',
42 async: true,
43 success: function (html) {
44 $("#content").html($(html).find(\'div[id=container]\').html());
45
46 //$("#content").html(html);
47 },
48 error: function(errorMsg) {
49 alert(errorMsg);
50 }
51 });
52 }
53 //解决方案二(缺点是content容器会被两次赋值,如不在加载完成之后的函数中进行数据处理,讲含有title、asp.net隐藏内容等标签)
54 function GetPageContent2(url) {
55 /* 想知道更多的load方法信息,请查阅jquery api */
56 $("#content").load(url + \' #container\', \'\', function (response, status, xhr) {
57 //response#是获取到的所有数据(未被截取),status#状态,成功或者失败,xhr#包含 XMLHttpRequest 对象
58 $("#content").html($(response).find(\'div[id=container]\').html());
59 });
60 }
61
62
查看代码
内容页面.aspx
1
2
3 DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DT ... gt%3B
4
5
6
7
8
9
10
11
12 Welcome to Content Page!
13
14
15
16
17
查看代码
注意:如果直接复制代码,请修改jquery文件路径
让我再补充一点,为什么不使用母版页
使用母版页,点击菜单会刷新整个网页,使用母版页会导致标签id改变。我想要实现的是点击菜单而不刷新页面
ajax抓取网页内容(【投稿】本文中爬虫常用的库,用之前需要先下载好)
网站优化 • 优采云 发表了文章 • 0 个评论 • 65 次浏览 • 2021-12-13 05:02
本文是读者提交的第二篇文章。如果你想投稿,可以后台联系我。作者:parkson知乎:喜欢的可以关注,点击原文直接阅读。
本文的一般路线
首先列出一些python中爬虫常用的库。您需要先下载它们,然后才能使用它们。本文假设您已经安装了相应的库。
下载库:
0、Urllib 库
1、requests 在发出请求时使用
2、将使用selenium自动化
解析库:
3、正则匹配重新解析网页
4、用于Xpath的lxml第三方库
5、beautifulSoup 解析网页
6、pyquery 网页解析库类似于beautifulSoup
数据库操作库:
7、pymysql 操作mysql数据
8、pymongo 操作MongoDB数据库
9、redis 非关系型数据库
10、jupyter 在线笔记本
一、 Ajax的简单理解
1、AJAX是一种技术,一种创建快速动态网页的技术;不是一种新的编程语言,而是一种使用现有标准的新方法。
2、AJAX=Asynchronous JavaScript and XML(异步 JavaScript 和 XML)
3、AJAX 是与服务器交换数据并更新部分网页的艺术,在不重新加载整个页面的情况下更新网页的某个部分。如果需要更新传统网页的内容(不使用 AJAX),则必须重新加载整个网页。
4、 Ajax 技术的核心是 XMLHttpRequest 对象(简称 XHR,即 AJAX 创建一个 XMLHttpRequest 对象并向服务器发送请求),它可以使用 XHR 对象从服务器获取数据,然后通过DOM Presentation将数据插入页面(AJAX加载的数据由浏览器渲染显示)。虽然名称中收录XML,但Ajax通信与数据格式无关(它是网页制作中的一种方法和技术),因此我们的数据格式可以是XML或JSON等格式。
二、 爬行AJAX动态加载网页案例
爬虫,简单的说就是自动从网上下载你感兴趣的信息。一般分为下载和解析两个步骤。
Ajax一般返回json格式的数据,直接用requests来post或获取(下载)ajax地址,返回json格式的数据,解析json数据得到你想要的信息(分析)。
如果我们使用AJAX加载的动态网页,我们如何抓取动态加载的内容?一般有两种方法:
方法一、通过selenium模拟浏览器爬行
方法二、通过浏览器review元素解析地址
case 一、URL保持不变,tab中第二个请求的URL按照一定的规则变化
以豆瓣电影为例:#/?sort=T&range=0,10&tags=%E5%8A%B1%E5%BF%97,点击加载更多刷新页面。
方法一、通过selenium模拟浏览器爬行,Beautiful Soup解析网页
这里有两种请求方式,设置一定的点击次数,不断点击加载更多
##设置一定的点击次数
from bs4 import BeautifulSoup
from selenium import webdriver
import time
import re
browser = webdriver.Chrome()###版本 68.0.3440.106(正式版本) (64 位)
browser.get('https://movie.douban.com/tag/#/?sort=T&range=0,10&tags=')
browser.implicitly_wait(3)##浏览器解释JS脚本是需要时间的,但实际上这个时间并不好确定,如果我们手动设定时间间隔的话,设置多了浪费时间,设置少了又会丢失数据
##implictly_wait函数则完美解决了这个问题,给他一个时间参数,它会只能等待,当js完全解释完毕就会自动执行下一步。
time.sleep(3)
browser.find_element_by_xpath('//*[@id="app"]/div/div[1]/div[1]/ul[4]/li[6]/span').click()###自动选择励志电影类型
i = 0
for i in range(5):##这里设置点击5次“加载更多”
browser.find_element_by_link_text("加载更多").click()
time.sleep(5)###如果网页没有完全加载,会出现点击错误,会点击到某个电影页面,所以加了一个睡眠时间。
##browswe.page_source是点击5次后的源码,用Beautiful Soup解析源码
soup = BeautifulSoup(browser.page_source, 'html.parser')
items = soup.find('div', class_=re.compile('list-wp'))
for item in items.find_all('a'):
Title = item.find('span', class_='title').text
Rate = item.find('span', class_='rate').text
Link = item.find('span',class_='pic').find('img').get('src')
print(Title,Rate,Link)
------------------------------------------------------------------------------------------------
###一直不断点击,直到加载完全
from bs4 import BeautifulSoup
from selenium import webdriver
import time
import re
browser = webdriver.Chrome()###版本 68.0.3440.106(正式版本) (64 位)
browser.get('https://movie.douban.com/tag/#/?sort=T&range=0,10&tags=')
browser.implicitly_wait(3)
time.sleep(3)
browser.find_element_by_xpath('//*[@id="app"]/div/div[1]/div[1]/ul[4]/li[6]/span').click()###自动选择励志电影类型
soup = BeautifulSoup(browser.page_source, 'html.parser')
while len(soup.select('.more'))>0:##soup.select(),返回类型是 list,判断只要长度大于0,就会一直不断点击。
browser.find_element_by_link_text("加载更多").click()
time.sleep(5)###如果网页没有完全加载,会出现点击错误,会点击到某个电影页面,所以加了一个睡眠时间。
soup = BeautifulSoup(browser.page_source, 'html.parser')
##将 加载更多 全部点击完成后,用Beautiful Soup解析网页源代码
items = soup.find('div', class_=re.compile('list-wp'))
for item in items.find_all('a'):
Title = item.find('span', class_='title').text
Rate = item.find('span', class_='rate').text
Link = item.find('span', class_='pic').find('img').get('src')
print(Title, Rate, Link)
方法二、直接根据tab中的URL规则构造第二个请求的URL
该网页通过 ajax 加载,一次显示 20 部电影。
点击加载更多
在Network选项卡中可以发现多了一个new_search,就是点击加载更多后需要重新加载的页面。对比几个new_searches,你会发现Request URL的结尾是start=i,i总是20的倍数,这样就可以直接写一个循环爬取多页电影信息了。
import requests
from requests.exceptions import RequestException
import time
import csv
import json
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'}
def get_one_page(url):
try:
response = requests.get(url,headers=headers)
if response.status_code == 200:
return response.json()##将返回的json数据转换为python可读的字典数据,.json是requests库自带的函数。
return None
except RequestException:
print("抓取失败")
def parse_one_page(d):
try:
datum = d['data']
for data in datum:
yield{
'Title':data['title'],
'Director':data['directors'],
'Actors':data['casts'],
'Rate':data['rate'],
'Link':data['url']
}
if data['Title','Director','Actors','Rate','Link'] == None:
return None
except Exception:
return None
def main():
for i in range(10):###这里就抓取10个网页,如果需求更多数据,将将数字改更大些即可。
url = 'https://movie.douban.com/j/new ... e%3D0,10&tags=%E5%8A%B1%E5%BF%97&start={}'.format(i*20)
d = get_one_page(url)
print('第{}页抓取完毕'.format(i+1))
for item in parse_one_page(d):
print(item)
##将输出字典依次写入csv文件中
with open('Movie.csv', 'a', newline='',encoding='utf-8') as f: # file_path 是 csv 文件存储的路径,默认路径
fieldnames = ['Title', 'Director', 'Actors', 'Rate', 'Link']
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
for item in parse_one_page(d):
writer.writerow(item)
if __name__=='__main__':
main()
case 二、URL不变,tab中第二个请求的URL不规则
以CSDN网站为例,抓取CSDN首页文章列表:CSDN-专业IT技术社区 当CSDN-专业IT技术社区下拉时URL保持不变,第二次请求的URL标签中不规则,网页下拉刷新。
方法一、通过selenium模拟浏览器爬行,用正则表达式解析网页
from selenium import webdriver
import re
import time
browser = webdriver.Chrome()
browser.get('https://www.csdn.net/')
browser.implicitly_wait(10)
i = 0
for i in range(5):###设置下拉5次,如果想获取更多信息,增加下拉次数即可
browser.execute_script('window.scrollTo(0, document.body.scrollHeight)')##下拉,execute_script可以将进度条下拉到最底部
time.sleep(5)##睡眠一下,防止网络延迟,卡顿等
data = []
pattern = re.compile('.*?(.*?)</a>.*?(.*?)</a>'
'.*?(.*?).*?',re.S)
items = re.findall(pattern,browser.page_source)##这里网页源代码为下拉5次后的代码
for item in items:
data.append({
'Title':item[0].strip(),
'Author' : item[1].strip(),
'ReadNum' : item[2] + item[3]
})
print(data)
方法二、通过浏览器review元素解析真实地址
import requests
headers = {'cookie':'uuid_tt_dd=3844871280714138949_20171108; kd_user_id=e61e2f88-9c4f-4cf7-88c7-68213cac17f7; UN=qq_40963426; BT=1521452212412; Hm_ct_6bcd52f51e9b3dce32bec4a3997715ac=1788*1*PC_VC; smidV2=20180626144357b069d2909d23ff73c3bc90ce183c8c57003acfcec7f57dd70; __utma=17226283.14643699.1533350144.1533350144.1534431588.2; __utmz=17226283.1533350144.1.1.utmcsr=zhuanlan.zhihu.com|utmccn=(referral)|utmcmd=referral|utmcct=/p/39165199/edit; TY_SESSION_ID=f49bdedd-c1d4-4f86-b254-22ab2e8f02f6; ViewMode=contents; UM_distinctid=165471259cb3e-02c5602643907b-5d4e211f-100200-165471259cc86; dc_session_id=10_1534471423488.794042; dc_tos=pdlzzq; Hm_lvt_6bcd52f51e9b3dce32bec4a3997715ac=1534515139,1534515661,1534515778,1534515830; Hm_lpvt_6bcd52f51e9b3dce32bec4a3997715ac=1534515830; ADHOC_MEMBERSHIP_CLIENT_ID1.0=d480c872-d4e9-33d9-d0e5-f076fc76aa83',
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'}
def get_page():
r =requests.get('https://www.csdn.net/api/artic ... 27%3B,headers=headers)
d=r.json()#一般ajax返回的都是json格式数据,将返回的数据json格式化,.json()是requests库自带函数
articles = d['articles']#字典形式
for article in articles:
yield {
'article':article['title'],
'Link':article['user_url'],
'View':article['views']
}
for i in get_page():
print(i)
##这里应该有关于抓取不同页文章标题的操作,但是还没有解决。
案例二参考链接:
注意:CSDN爬取基础咨询需要注意会有top信息,使用selenium+Beautiful Soup或者xpath解析时需要单独注意,否则代码会一直报错。
不管是静态网页还是动态网页,爬虫的核心都是下载和解析。 查看全部
ajax抓取网页内容(【投稿】本文中爬虫常用的库,用之前需要先下载好)
本文是读者提交的第二篇文章。如果你想投稿,可以后台联系我。作者:parkson知乎:喜欢的可以关注,点击原文直接阅读。
本文的一般路线
首先列出一些python中爬虫常用的库。您需要先下载它们,然后才能使用它们。本文假设您已经安装了相应的库。
下载库:
0、Urllib 库
1、requests 在发出请求时使用
2、将使用selenium自动化
解析库:
3、正则匹配重新解析网页
4、用于Xpath的lxml第三方库
5、beautifulSoup 解析网页
6、pyquery 网页解析库类似于beautifulSoup
数据库操作库:
7、pymysql 操作mysql数据
8、pymongo 操作MongoDB数据库
9、redis 非关系型数据库
10、jupyter 在线笔记本
一、 Ajax的简单理解
1、AJAX是一种技术,一种创建快速动态网页的技术;不是一种新的编程语言,而是一种使用现有标准的新方法。
2、AJAX=Asynchronous JavaScript and XML(异步 JavaScript 和 XML)
3、AJAX 是与服务器交换数据并更新部分网页的艺术,在不重新加载整个页面的情况下更新网页的某个部分。如果需要更新传统网页的内容(不使用 AJAX),则必须重新加载整个网页。
4、 Ajax 技术的核心是 XMLHttpRequest 对象(简称 XHR,即 AJAX 创建一个 XMLHttpRequest 对象并向服务器发送请求),它可以使用 XHR 对象从服务器获取数据,然后通过DOM Presentation将数据插入页面(AJAX加载的数据由浏览器渲染显示)。虽然名称中收录XML,但Ajax通信与数据格式无关(它是网页制作中的一种方法和技术),因此我们的数据格式可以是XML或JSON等格式。
二、 爬行AJAX动态加载网页案例
爬虫,简单的说就是自动从网上下载你感兴趣的信息。一般分为下载和解析两个步骤。
Ajax一般返回json格式的数据,直接用requests来post或获取(下载)ajax地址,返回json格式的数据,解析json数据得到你想要的信息(分析)。
如果我们使用AJAX加载的动态网页,我们如何抓取动态加载的内容?一般有两种方法:
方法一、通过selenium模拟浏览器爬行
方法二、通过浏览器review元素解析地址
case 一、URL保持不变,tab中第二个请求的URL按照一定的规则变化
以豆瓣电影为例:#/?sort=T&range=0,10&tags=%E5%8A%B1%E5%BF%97,点击加载更多刷新页面。
方法一、通过selenium模拟浏览器爬行,Beautiful Soup解析网页
这里有两种请求方式,设置一定的点击次数,不断点击加载更多
##设置一定的点击次数
from bs4 import BeautifulSoup
from selenium import webdriver
import time
import re
browser = webdriver.Chrome()###版本 68.0.3440.106(正式版本) (64 位)
browser.get('https://movie.douban.com/tag/#/?sort=T&range=0,10&tags=')
browser.implicitly_wait(3)##浏览器解释JS脚本是需要时间的,但实际上这个时间并不好确定,如果我们手动设定时间间隔的话,设置多了浪费时间,设置少了又会丢失数据
##implictly_wait函数则完美解决了这个问题,给他一个时间参数,它会只能等待,当js完全解释完毕就会自动执行下一步。
time.sleep(3)
browser.find_element_by_xpath('//*[@id="app"]/div/div[1]/div[1]/ul[4]/li[6]/span').click()###自动选择励志电影类型
i = 0
for i in range(5):##这里设置点击5次“加载更多”
browser.find_element_by_link_text("加载更多").click()
time.sleep(5)###如果网页没有完全加载,会出现点击错误,会点击到某个电影页面,所以加了一个睡眠时间。
##browswe.page_source是点击5次后的源码,用Beautiful Soup解析源码
soup = BeautifulSoup(browser.page_source, 'html.parser')
items = soup.find('div', class_=re.compile('list-wp'))
for item in items.find_all('a'):
Title = item.find('span', class_='title').text
Rate = item.find('span', class_='rate').text
Link = item.find('span',class_='pic').find('img').get('src')
print(Title,Rate,Link)
------------------------------------------------------------------------------------------------
###一直不断点击,直到加载完全
from bs4 import BeautifulSoup
from selenium import webdriver
import time
import re
browser = webdriver.Chrome()###版本 68.0.3440.106(正式版本) (64 位)
browser.get('https://movie.douban.com/tag/#/?sort=T&range=0,10&tags=')
browser.implicitly_wait(3)
time.sleep(3)
browser.find_element_by_xpath('//*[@id="app"]/div/div[1]/div[1]/ul[4]/li[6]/span').click()###自动选择励志电影类型
soup = BeautifulSoup(browser.page_source, 'html.parser')
while len(soup.select('.more'))>0:##soup.select(),返回类型是 list,判断只要长度大于0,就会一直不断点击。
browser.find_element_by_link_text("加载更多").click()
time.sleep(5)###如果网页没有完全加载,会出现点击错误,会点击到某个电影页面,所以加了一个睡眠时间。
soup = BeautifulSoup(browser.page_source, 'html.parser')
##将 加载更多 全部点击完成后,用Beautiful Soup解析网页源代码
items = soup.find('div', class_=re.compile('list-wp'))
for item in items.find_all('a'):
Title = item.find('span', class_='title').text
Rate = item.find('span', class_='rate').text
Link = item.find('span', class_='pic').find('img').get('src')
print(Title, Rate, Link)
方法二、直接根据tab中的URL规则构造第二个请求的URL
该网页通过 ajax 加载,一次显示 20 部电影。
点击加载更多
在Network选项卡中可以发现多了一个new_search,就是点击加载更多后需要重新加载的页面。对比几个new_searches,你会发现Request URL的结尾是start=i,i总是20的倍数,这样就可以直接写一个循环爬取多页电影信息了。
import requests
from requests.exceptions import RequestException
import time
import csv
import json
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'}
def get_one_page(url):
try:
response = requests.get(url,headers=headers)
if response.status_code == 200:
return response.json()##将返回的json数据转换为python可读的字典数据,.json是requests库自带的函数。
return None
except RequestException:
print("抓取失败")
def parse_one_page(d):
try:
datum = d['data']
for data in datum:
yield{
'Title':data['title'],
'Director':data['directors'],
'Actors':data['casts'],
'Rate':data['rate'],
'Link':data['url']
}
if data['Title','Director','Actors','Rate','Link'] == None:
return None
except Exception:
return None
def main():
for i in range(10):###这里就抓取10个网页,如果需求更多数据,将将数字改更大些即可。
url = 'https://movie.douban.com/j/new ... e%3D0,10&tags=%E5%8A%B1%E5%BF%97&start={}'.format(i*20)
d = get_one_page(url)
print('第{}页抓取完毕'.format(i+1))
for item in parse_one_page(d):
print(item)
##将输出字典依次写入csv文件中
with open('Movie.csv', 'a', newline='',encoding='utf-8') as f: # file_path 是 csv 文件存储的路径,默认路径
fieldnames = ['Title', 'Director', 'Actors', 'Rate', 'Link']
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
for item in parse_one_page(d):
writer.writerow(item)
if __name__=='__main__':
main()
case 二、URL不变,tab中第二个请求的URL不规则
以CSDN网站为例,抓取CSDN首页文章列表:CSDN-专业IT技术社区 当CSDN-专业IT技术社区下拉时URL保持不变,第二次请求的URL标签中不规则,网页下拉刷新。
方法一、通过selenium模拟浏览器爬行,用正则表达式解析网页
from selenium import webdriver
import re
import time
browser = webdriver.Chrome()
browser.get('https://www.csdn.net/')
browser.implicitly_wait(10)
i = 0
for i in range(5):###设置下拉5次,如果想获取更多信息,增加下拉次数即可
browser.execute_script('window.scrollTo(0, document.body.scrollHeight)')##下拉,execute_script可以将进度条下拉到最底部
time.sleep(5)##睡眠一下,防止网络延迟,卡顿等
data = []
pattern = re.compile('.*?(.*?)</a>.*?(.*?)</a>'
'.*?(.*?).*?',re.S)
items = re.findall(pattern,browser.page_source)##这里网页源代码为下拉5次后的代码
for item in items:
data.append({
'Title':item[0].strip(),
'Author' : item[1].strip(),
'ReadNum' : item[2] + item[3]
})
print(data)
方法二、通过浏览器review元素解析真实地址
import requests
headers = {'cookie':'uuid_tt_dd=3844871280714138949_20171108; kd_user_id=e61e2f88-9c4f-4cf7-88c7-68213cac17f7; UN=qq_40963426; BT=1521452212412; Hm_ct_6bcd52f51e9b3dce32bec4a3997715ac=1788*1*PC_VC; smidV2=20180626144357b069d2909d23ff73c3bc90ce183c8c57003acfcec7f57dd70; __utma=17226283.14643699.1533350144.1533350144.1534431588.2; __utmz=17226283.1533350144.1.1.utmcsr=zhuanlan.zhihu.com|utmccn=(referral)|utmcmd=referral|utmcct=/p/39165199/edit; TY_SESSION_ID=f49bdedd-c1d4-4f86-b254-22ab2e8f02f6; ViewMode=contents; UM_distinctid=165471259cb3e-02c5602643907b-5d4e211f-100200-165471259cc86; dc_session_id=10_1534471423488.794042; dc_tos=pdlzzq; Hm_lvt_6bcd52f51e9b3dce32bec4a3997715ac=1534515139,1534515661,1534515778,1534515830; Hm_lpvt_6bcd52f51e9b3dce32bec4a3997715ac=1534515830; ADHOC_MEMBERSHIP_CLIENT_ID1.0=d480c872-d4e9-33d9-d0e5-f076fc76aa83',
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'}
def get_page():
r =requests.get('https://www.csdn.net/api/artic ... 27%3B,headers=headers)
d=r.json()#一般ajax返回的都是json格式数据,将返回的数据json格式化,.json()是requests库自带函数
articles = d['articles']#字典形式
for article in articles:
yield {
'article':article['title'],
'Link':article['user_url'],
'View':article['views']
}
for i in get_page():
print(i)
##这里应该有关于抓取不同页文章标题的操作,但是还没有解决。
案例二参考链接:
注意:CSDN爬取基础咨询需要注意会有top信息,使用selenium+Beautiful Soup或者xpath解析时需要单独注意,否则代码会一直报错。
不管是静态网页还是动态网页,爬虫的核心都是下载和解析。
ajax抓取网页内容(越来越多的网站采用Ajax技术解决方法放弃井号结构)
网站优化 • 优采云 发表了文章 • 0 个评论 • 42 次浏览 • 2021-12-13 04:28
越来越多的网站开始采用“单页应用”。
整个网站只有一个网页,利用Ajax技术根据用户的输入加载不同的内容。
这种方式的优点是用户体验好,节省流量。缺点是AJAX内容无法被搜索引擎抓取。例如,您有一个 网站。
用户可以通过带有哈希结构的 URL 看到不同的内容。
#1
#2
#3
但是,搜索引擎只会抓取并忽略井号,因此它们无法索引内容。
为了解决这个问题,谷歌提出了“哈希+感叹号”的结构。
#!1
当谷歌找到上述网址时,它会自动抓取另一个网址:
只要你把 AJAX 内容放到这个 URL 上,Google 就会收录。但问题是“哈希+感叹号”非常丑陋和繁琐。Twitter曾经使用这种结构,它把
改成
#!/ruanyf
结果,用户抱怨连连,只用了半年时间就废了。
那么,有没有什么办法可以让搜索引擎在保持一个更直观的URL的同时抓取AJAX内容呢?
一直觉得没办法,直到前两天看到一位Discourse创始人的解决方案,忍不住尖叫起来。
Discourse 是一个严重依赖 Ajax 的论坛程序,但它必须让 Google收录 内容。它的解决方案是放弃hash结构,使用History API。
所谓History API,就是在不刷新页面的情况下,改变浏览器地址栏中显示的URL(准确的说是改变网页的当前状态)。这是一个示例,您单击上面的按钮开始播放音乐。然后,点击下面的链接,地址栏中的URL变了,但音乐播放没有中断!
History API 的详细介绍超出了本文章的范围。简单的说到这里,它的作用就是给浏览器的History对象添加一条记录。
window.history.pushState(state object, title, url);
上面这行命令可以让地址栏中出现一个新的 URL。History对象的pushState方法接受三个参数,新的URL为第三个参数,前两个参数可以为null。
window.history.pushState(null, null, newURL);
目前主流浏览器都支持这种方式:Chrome(26.0+)、Firefox(20.0+)、IE(10.0+)、Safari(5.1+)、歌剧 (12.1+)。
这是罗宾沃德的方法。
首先用History API替换hash结构,让每一个hash符号变成一个正常路径的URL,这样搜索引擎就会抓取每一个网页。
/1
/2
/3
然后,定义一个 JavaScript 函数来处理 Ajax 部分并根据 URL 抓取内容(假设使用 jQuery)。
功能锚点击(链接){
var linkSplit = link.split('/').pop();
$.get('api/' + linkSplit, function(data) {
$('#content').html(数据);
});
}
然后定义鼠标的点击事件。
$('#container').on('click','a', function(e) {
window.history.pushState(null, null, $(this).attr('href'));
anchorClick($(this).attr('href'));
e.preventDefault();
});
还要考虑用户点击浏览器的“前进/后退”按钮。这时候会触发History对象的popstate事件。
window.addEventListener('popstate', function(e) {
锚点击(位置。路径名);
});
定义以上三段代码后,无需刷新页面即可显示正常路径URL和AJAX内容。
最后,设置服务器端。
因为没有使用 hashtag 结构,所以每个 URL 都是不同的请求。因此,服务器需要向所有这些请求返回具有以下结构的网页,以防止 404 错误。
如果你仔细看上面的代码,你会发现里面有一个 noscript 标签。这就是秘密。
我们将所有我们想要搜索引擎的内容放在了 noscript 标签中。在这种情况下,用户仍然可以在不刷新页面的情况下进行AJAX操作,但是搜索引擎会收录每个页面的主要内容! 查看全部
ajax抓取网页内容(越来越多的网站采用Ajax技术解决方法放弃井号结构)
越来越多的网站开始采用“单页应用”。
整个网站只有一个网页,利用Ajax技术根据用户的输入加载不同的内容。
这种方式的优点是用户体验好,节省流量。缺点是AJAX内容无法被搜索引擎抓取。例如,您有一个 网站。
用户可以通过带有哈希结构的 URL 看到不同的内容。
#1
#2
#3
但是,搜索引擎只会抓取并忽略井号,因此它们无法索引内容。
为了解决这个问题,谷歌提出了“哈希+感叹号”的结构。
#!1
当谷歌找到上述网址时,它会自动抓取另一个网址:
只要你把 AJAX 内容放到这个 URL 上,Google 就会收录。但问题是“哈希+感叹号”非常丑陋和繁琐。Twitter曾经使用这种结构,它把
改成
#!/ruanyf
结果,用户抱怨连连,只用了半年时间就废了。
那么,有没有什么办法可以让搜索引擎在保持一个更直观的URL的同时抓取AJAX内容呢?
一直觉得没办法,直到前两天看到一位Discourse创始人的解决方案,忍不住尖叫起来。
Discourse 是一个严重依赖 Ajax 的论坛程序,但它必须让 Google收录 内容。它的解决方案是放弃hash结构,使用History API。
所谓History API,就是在不刷新页面的情况下,改变浏览器地址栏中显示的URL(准确的说是改变网页的当前状态)。这是一个示例,您单击上面的按钮开始播放音乐。然后,点击下面的链接,地址栏中的URL变了,但音乐播放没有中断!
History API 的详细介绍超出了本文章的范围。简单的说到这里,它的作用就是给浏览器的History对象添加一条记录。
window.history.pushState(state object, title, url);
上面这行命令可以让地址栏中出现一个新的 URL。History对象的pushState方法接受三个参数,新的URL为第三个参数,前两个参数可以为null。
window.history.pushState(null, null, newURL);
目前主流浏览器都支持这种方式:Chrome(26.0+)、Firefox(20.0+)、IE(10.0+)、Safari(5.1+)、歌剧 (12.1+)。
这是罗宾沃德的方法。
首先用History API替换hash结构,让每一个hash符号变成一个正常路径的URL,这样搜索引擎就会抓取每一个网页。
/1
/2
/3
然后,定义一个 JavaScript 函数来处理 Ajax 部分并根据 URL 抓取内容(假设使用 jQuery)。
功能锚点击(链接){
var linkSplit = link.split('/').pop();
$.get('api/' + linkSplit, function(data) {
$('#content').html(数据);
});
}
然后定义鼠标的点击事件。
$('#container').on('click','a', function(e) {
window.history.pushState(null, null, $(this).attr('href'));
anchorClick($(this).attr('href'));
e.preventDefault();
});
还要考虑用户点击浏览器的“前进/后退”按钮。这时候会触发History对象的popstate事件。
window.addEventListener('popstate', function(e) {
锚点击(位置。路径名);
});
定义以上三段代码后,无需刷新页面即可显示正常路径URL和AJAX内容。
最后,设置服务器端。
因为没有使用 hashtag 结构,所以每个 URL 都是不同的请求。因此,服务器需要向所有这些请求返回具有以下结构的网页,以防止 404 错误。
如果你仔细看上面的代码,你会发现里面有一个 noscript 标签。这就是秘密。
我们将所有我们想要搜索引擎的内容放在了 noscript 标签中。在这种情况下,用户仍然可以在不刷新页面的情况下进行AJAX操作,但是搜索引擎会收录每个页面的主要内容!
ajax抓取网页内容(这是网页中元素与打印的简单对应关系-安亲宝)
网站优化 • 优采云 发表了文章 • 0 个评论 • 42 次浏览 • 2021-12-09 21:09
目前,浏览器对于网页页眉页脚的打印还存在很大的不足。可能有一些方法可以借助css来修复fixed position或者flexlayout,但是效果并不理想。
不过在最近更新的chrome to table打印中,增加了对等价元素的优化支持,解决了表格中标题和内容会被截断的问题。其实我们可以利用这个特性简单的打印页眉页脚。
这是网页中 HTML 元素和打印之间的简单对应关系:
______________________
| 头 | 标题
|____________|
| |
| | 内容
| 身体 |
| |
| |
|____________|
| 脚 | 页脚
|____________|
HTML代码示例:
这是页头? 列1 列2 FOX JUMP A RIVER GO AWAY 这是页脚
生产环境下测试效果:
目前在用Chrome打印时发现的一些问题:
1) Thead 和 tfoot 只有在表格内容超过一页时才会起作用。
2) 当内容短于一页时,tfoot中的内容将不会显示在页面底部。
3) 页面多时,页面底部不显示最后一页的tfoot
总体来说效果比之前好很多,还可以接受。网页基本可以达到和打印机软件一样的效果。 查看全部
ajax抓取网页内容(这是网页中元素与打印的简单对应关系-安亲宝)
目前,浏览器对于网页页眉页脚的打印还存在很大的不足。可能有一些方法可以借助css来修复fixed position或者flexlayout,但是效果并不理想。
不过在最近更新的chrome to table打印中,增加了对等价元素的优化支持,解决了表格中标题和内容会被截断的问题。其实我们可以利用这个特性简单的打印页眉页脚。
这是网页中 HTML 元素和打印之间的简单对应关系:
______________________
| 头 | 标题
|____________|
| |
| | 内容
| 身体 |
| |
| |
|____________|
| 脚 | 页脚
|____________|
HTML代码示例:
这是页头? 列1 列2 FOX JUMP A RIVER GO AWAY 这是页脚
生产环境下测试效果:

目前在用Chrome打印时发现的一些问题:
1) Thead 和 tfoot 只有在表格内容超过一页时才会起作用。
2) 当内容短于一页时,tfoot中的内容将不会显示在页面底部。
3) 页面多时,页面底部不显示最后一页的tfoot
总体来说效果比之前好很多,还可以接受。网页基本可以达到和打印机软件一样的效果。
ajax抓取网页内容(获取JavaScript脚本可以设计响应信息为JavaScript代码,它是可以执行的命令或脚本)
网站优化 • 优采云 发表了文章 • 0 个评论 • 48 次浏览 • 2021-12-05 17:22
获取 JavaScript 脚本
响应信息可以设计为 JavaScript 代码。这里的代码不同于 JSON 数据。它是可以执行的命令或脚本。
例子:在服务端指定JS函数
AJAX测试
按钮
function f() {
var ajax = createXMLHTTPObject();
ajax.onreadystatechange = function(){
if(ajax.readyState == 4 && ajax.status == 200){
var info = ajax.responseText;
var o = eval("(" + info + ")" + "()");//调用eval()方法把JavaScript字符串转换为本地脚本
alert(o);//返回客户端当前日期
}
}
ajax.open("get", "response.js",true);
ajax.send();
}
响应.js:
function (){
var d = new Date();
return d.toString();
}
点击按钮,会弹出提示信息:
注意:转换时需要在字符串签名后加两个括号:一个收录函数结构,一个表示调用函数。通常,JavaScript 代码很少用作响应信息的格式,因为它无法传递更丰富的信息,并且 JavaScript 脚本容易存在安全风险。 查看全部
ajax抓取网页内容(获取JavaScript脚本可以设计响应信息为JavaScript代码,它是可以执行的命令或脚本)
获取 JavaScript 脚本
响应信息可以设计为 JavaScript 代码。这里的代码不同于 JSON 数据。它是可以执行的命令或脚本。
例子:在服务端指定JS函数
AJAX测试
按钮
function f() {
var ajax = createXMLHTTPObject();
ajax.onreadystatechange = function(){
if(ajax.readyState == 4 && ajax.status == 200){
var info = ajax.responseText;
var o = eval("(" + info + ")" + "()");//调用eval()方法把JavaScript字符串转换为本地脚本
alert(o);//返回客户端当前日期
}
}
ajax.open("get", "response.js",true);
ajax.send();
}
响应.js:
function (){
var d = new Date();
return d.toString();
}
点击按钮,会弹出提示信息:

注意:转换时需要在字符串签名后加两个括号:一个收录函数结构,一个表示调用函数。通常,JavaScript 代码很少用作响应信息的格式,因为它无法传递更丰富的信息,并且 JavaScript 脚本容易存在安全风险。
ajax抓取网页内容(请求网页源数据的代码:接下来应该解析网页中的数据 )
网站优化 • 优采云 发表了文章 • 0 个评论 • 38 次浏览 • 2022-01-02 08:02
)
一般我们从网页爬取内容的时候,都是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中的信息:
查看全部
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中的信息:
ajax抓取网页内容(ScreamingFrogSEOSpiderforMac软件介绍(一)_)
网站优化 • 优采云 发表了文章 • 0 个评论 • 48 次浏览 • 2021-12-31 19:18
Screaming Frog SEO Spider for Mac 是一款专门用于抓取网址进行分析的网络爬虫开发工具。您可以使用本软件快速抓取网站中可能出现的断链和服务器错误,或者识别网站中临时和永久重定向的链接周期,也可以检查重复问题信息中心可能出现的URL、页面标题、描述、内容等。
Screaming Frog SEO Spider for Mac 软件介绍
Screaming Frog SEO Spider for Mac 是一款网站 爬虫,可让您爬取网站 的网址,获取关键元素、分析和审计技术以及现场搜索引擎优化。
Mac 版 Screaming Frog SEO Spider 的功能
1、找到失效链接
立即抓取 网站 并找到断开的链接 (404) 和服务器错误。批量导出错误和源网址进行修复或发送给开发者。
2、审核重定向
查找临时和永久重定向,识别重定向链和循环,或上传 URL 列表以在网站迁移期间进行审核。
3、分析页面标题和元数据
在抓取过程中分析页面标题和元描述,识别网站过长、缺失、缺失或重复的内容。
4、发现重复内容
使用 md5 算法检查和查找完全重复的 URL、部分重复的元素(例如页面标题、描述或标题)并查找低内容页面。
5、使用XPath提取数据
使用 CSS Path、XPath 或正则表达式从网页的 HTML 中采集任何数据。这可能包括社交元标签、其他标题、价格、SKU 或更多!
6、查看机器人和说明
查看被 robots.txt、元机器人或 X-Robots-Tag 指令(例如“noindex”或“nofollow”)以及规范和 rel="next" 和 rel="prev" 阻止的 URL。
7、生成 XML 站点地图
快速创建 XML 站点地图和图片 XML 站点地图,并通过 URL 进行高级配置,包括最后修改、优先级和更改频率。
8、与 Google Analytics 集成
连接到 Google Analytics API 并获取用于抓取功能的用户数据,例如会话或跳出率以及着陆页的转化、目标、交易和收入。
9、抓取 JavaScript网站
使用集成的 Chromium WRS 来渲染网页以抓取动态的、富含 JavaScript 的 网站 和框架,例如 Angular、React 和 Vue.js。
10、可视化网站架构
使用交互式爬虫和目录强制地图和树形地图站点来直观地评估内部链接和 URL 结构。
Screaming Frog SEO Spider for Mac 快速总结
错误 - 客户端错误,例如断开的链接和服务器错误(无响应、4XX、5XX)。
永久重定向、临时重定向(3XX 响应)和 JS 重定向。
被阻止的网址 - robots.txt 协议不允许查看和审查网址。
被阻止的资源 - 在演示模式下查看和审核被阻止的资源。
外部链接-所有外部链接及其状态代码。
协议 - URL 是安全 (HTTP) 还是不安全 (HTTP)。
URI 问题 - 非 ASCII 字符、下划线、大写字符、参数或长 URL。
重复页面-哈希/MD5校验和算法来检查完全重复的页面。
页面标题缺失、重复、超过65个字符、较短、像素宽度被截断、等于或大于h1。
元描述-缺失、重复、超过 156 个字符、短、截断或像素宽度多。
元关键字 - 主要供参考,因为它们未被 Google、Bing 或 Yahoo 使用。
文件大小-网址和图片的大小。
响应时间。
最后修改的标题。
页面(抓取)深度。
字数统计。
H1-缺失,重复,超过70个字符,不止一个。
H2-缺失,重复,超过70个字符,不止一个。
元机器人索引、无索引、follow、nofollow、noarchive、nosnippet、noodp、noydir等
元刷新——包括目标页面和时间延迟。 查看全部
ajax抓取网页内容(ScreamingFrogSEOSpiderforMac软件介绍(一)_)
Screaming Frog SEO Spider for Mac 是一款专门用于抓取网址进行分析的网络爬虫开发工具。您可以使用本软件快速抓取网站中可能出现的断链和服务器错误,或者识别网站中临时和永久重定向的链接周期,也可以检查重复问题信息中心可能出现的URL、页面标题、描述、内容等。
Screaming Frog SEO Spider for Mac 软件介绍
Screaming Frog SEO Spider for Mac 是一款网站 爬虫,可让您爬取网站 的网址,获取关键元素、分析和审计技术以及现场搜索引擎优化。
Mac 版 Screaming Frog SEO Spider 的功能
1、找到失效链接
立即抓取 网站 并找到断开的链接 (404) 和服务器错误。批量导出错误和源网址进行修复或发送给开发者。
2、审核重定向
查找临时和永久重定向,识别重定向链和循环,或上传 URL 列表以在网站迁移期间进行审核。
3、分析页面标题和元数据
在抓取过程中分析页面标题和元描述,识别网站过长、缺失、缺失或重复的内容。
4、发现重复内容
使用 md5 算法检查和查找完全重复的 URL、部分重复的元素(例如页面标题、描述或标题)并查找低内容页面。
5、使用XPath提取数据
使用 CSS Path、XPath 或正则表达式从网页的 HTML 中采集任何数据。这可能包括社交元标签、其他标题、价格、SKU 或更多!
6、查看机器人和说明
查看被 robots.txt、元机器人或 X-Robots-Tag 指令(例如“noindex”或“nofollow”)以及规范和 rel="next" 和 rel="prev" 阻止的 URL。
7、生成 XML 站点地图
快速创建 XML 站点地图和图片 XML 站点地图,并通过 URL 进行高级配置,包括最后修改、优先级和更改频率。
8、与 Google Analytics 集成
连接到 Google Analytics API 并获取用于抓取功能的用户数据,例如会话或跳出率以及着陆页的转化、目标、交易和收入。
9、抓取 JavaScript网站
使用集成的 Chromium WRS 来渲染网页以抓取动态的、富含 JavaScript 的 网站 和框架,例如 Angular、React 和 Vue.js。
10、可视化网站架构
使用交互式爬虫和目录强制地图和树形地图站点来直观地评估内部链接和 URL 结构。
Screaming Frog SEO Spider for Mac 快速总结
错误 - 客户端错误,例如断开的链接和服务器错误(无响应、4XX、5XX)。
永久重定向、临时重定向(3XX 响应)和 JS 重定向。
被阻止的网址 - robots.txt 协议不允许查看和审查网址。
被阻止的资源 - 在演示模式下查看和审核被阻止的资源。
外部链接-所有外部链接及其状态代码。
协议 - URL 是安全 (HTTP) 还是不安全 (HTTP)。
URI 问题 - 非 ASCII 字符、下划线、大写字符、参数或长 URL。
重复页面-哈希/MD5校验和算法来检查完全重复的页面。
页面标题缺失、重复、超过65个字符、较短、像素宽度被截断、等于或大于h1。
元描述-缺失、重复、超过 156 个字符、短、截断或像素宽度多。
元关键字 - 主要供参考,因为它们未被 Google、Bing 或 Yahoo 使用。
文件大小-网址和图片的大小。
响应时间。
最后修改的标题。
页面(抓取)深度。
字数统计。
H1-缺失,重复,超过70个字符,不止一个。
H2-缺失,重复,超过70个字符,不止一个。
元机器人索引、无索引、follow、nofollow、noarchive、nosnippet、noodp、noydir等
元刷新——包括目标页面和时间延迟。
ajax抓取网页内容(目标网络爬虫的是做什么的?手动写一个简单的网络)
网站优化 • 优采云 发表了文章 • 0 个评论 • 42 次浏览 • 2021-12-31 19:14
目标
网络爬虫有什么作用?手动编写一个简单的网络爬虫;
1. 网络爬虫
1.1. 姓名
1.2. 简介
2.流程
通过上面的流程图,您可以大致了解网络爬虫是做什么的,并基于这些,您可以设计一个简单的网络爬虫。
一个简单的爬虫。必要的功能:
发送请求和获取响应的功能;解析响应的功能;存储过滤数据的功能;处理解析出的URL路径的功能;
2.1. 兴趣点
3. 分类
4. 创意分析
首先观察我们爬虫的起始页面是:
所有喜讯信息的URL用XPath表达式表示://div[@class='main_l']/ul/li
相关数据
好的,我们已经在上面的代码中找到了需要获取的关键信息的XPath表达式,接下来就可以正式编写代码来实现了。
5.代码实现
代码实现部分使用了webmagic框架,因为比使用基本的Java网络编程要简单得多。注意:对于 webmagic 框架,您可以阅读以下讲义
5.1.代码结构
5.2.程序入口
Demo.java
/**
* 程序入口
*/
public class Demo {
public static void main(String[] args) {
// 爬取开始
Spider
// 爬取过程
.create(new WanhoPageProcessor())
// 爬取结果保存
.addPipeline(new WanhoPipeline())
// 爬取的第一个页面
.addUrl("http://www.wanho.net/a/jyxb/")
// 启用的线程数
.thread(5).run();
}
}
5.3.爬取过程
package net.wanho.wanhosite;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.processor.PageProcessor;
import us.codecraft.webmagic.selector.Html;
public class WanhoPageProcessor implements PageProcessor {
// 部分一:抓取网站的相关配置,包括编码、抓取间隔、重试次数等
private Site site = Site
.me()
.setTimeOut(10000)
.setRetryTimes(3)
.setSleepTime(1000)
.setCharset("UTF-8");
// 獲得站點
@Override
public Site getSite() {
return site;
}
//爬取過程
@Override
public void process(Page page) {
//获取当前页的所有喜报
List list = page.getHtml().xpath("//div[@class='main_l']/ul/li").all();
//要保存喜报的集合
Vector voLst = new Vector();
//遍历喜报
String title;
String content;
String img;
for (String item : list) {
Html tmp = Html.create(item);
//标题
title = tmp.xpath("//div[@class='content']/h4/a/text()").toString();
//内容
content = tmp.xpath("//div[@class='content']/p/text()").toString();
//图片路径
img = tmp.xpath("//a/img/@src").toString();
//加入集合
ArticleVo vo = new ArticleVo(title, content, img);
voLst.add(vo);
}
//保存数据至page中,后续进行持久化
page.putField("e_list", voLst);
//加载其它页
page.addTargetRequests( getOtherUrls());
}
//其它页
public List getOtherUrls(){
List urlLsts = new ArrayList();
for(int i=2;i网络选项),然后找到那些加载数据的json请求,最后直接请求那些URL获取数据来模拟浏览器请求,等待一个从满载开始的一定时间 只需从完成的页面中获取数据。这类爬虫通常需要内嵌浏览器内核,如:webmagic、phantom.js、HttpUnit等
接下来,我将通过我们的官网和大家一起分析一下如何实现这样的爬虫:
首先观察我们爬虫的起始页面是:
从上图可以看出,我们可以从首页的HTML源代码中直观的找到我们需要的标题、内容、图片链接等信息。那么我们可以通过什么方式提取这些目标数据呢?
其实提取页面元素的webmagic框架主要支持以下三种方法:
XPath 正则表达式 CSS 选择器
当然,选择哪种方式提取数据需要根据具体页面进行分析。在这个例子中,很明显使用XPath提取数据是最方便的
所以,那我直接给出我们需要爬取的数据的XPath路径:
注:“//”表示从相对路径开始,第一个“/”表示从页面路径开始;两个/后面的内容代表一个元素,括号内的内容表示该元素的执行属性,如:h1[@class='entry-title']表示:有一个h1元素,其class属性为“条目标题”
6.2.3. 页面数据提取:
使用webmagic提取页面数据时,需要自定义一个类来实现PageProcessor接口。
该类实现PageProcessor接口的主要功能如下三步:
爬虫配置:爬取页面的配置,包括编码、爬取间隔、重试次数等页面元素的提取:使用正则表达式或者XPath提取页面元素。新链接的发现:从一个页面找到的链接到其他待抓取的目标页面
<p>package net.wanho.wanhosite;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.processor.PageProcessor;
import us.codecraft.webmagic.selector.Html;
public class WanhoPageProcessor implements PageProcessor {
// 部分一:抓取网站的相关配置,包括编码、抓取间隔、重试次数等
private Site site = Site
.me()
.setTimeOut(10000)
.setRetryTimes(3)
.setSleepTime(1000)
.setCharset("UTF-8");
// 獲得站點
@Override
public Site getSite() {
return site;
}
//爬取過程
@Override
public void process(Page page) {
//获取当前页的所有喜报
List list = page.getHtml().xpath("//div[@class='main_l']/ul/li").all();
//要保存喜报的集合
Vector voLst = new Vector();
//遍历喜报
String title;
String content;
String img;
for (String item : list) {
Html tmp = Html.create(item);
//标题
title = tmp.xpath("//div[@class='content']/h4/a/text()").toString();
//内容
content = tmp.xpath("//div[@class='content']/p/text()").toString();
//图片路径
img = tmp.xpath("//a/img/@src").toString();
//加入集合
ArticleVo vo = new ArticleVo(title, content, img);
voLst.add(vo);
}
//保存数据至page中,后续进行持久化
page.putField("e_list", voLst);
//加载其它页
page.addTargetRequests( getOtherUrls());
}
//其它页
public List getOtherUrls(){
List urlLsts = new ArrayList();
for(int i=2;i 查看全部
ajax抓取网页内容(目标网络爬虫的是做什么的?手动写一个简单的网络)
目标
网络爬虫有什么作用?手动编写一个简单的网络爬虫;
1. 网络爬虫
1.1. 姓名
1.2. 简介
2.流程
通过上面的流程图,您可以大致了解网络爬虫是做什么的,并基于这些,您可以设计一个简单的网络爬虫。
一个简单的爬虫。必要的功能:
发送请求和获取响应的功能;解析响应的功能;存储过滤数据的功能;处理解析出的URL路径的功能;
2.1. 兴趣点
3. 分类
4. 创意分析
首先观察我们爬虫的起始页面是:
所有喜讯信息的URL用XPath表达式表示://div[@class='main_l']/ul/li
相关数据
好的,我们已经在上面的代码中找到了需要获取的关键信息的XPath表达式,接下来就可以正式编写代码来实现了。
5.代码实现
代码实现部分使用了webmagic框架,因为比使用基本的Java网络编程要简单得多。注意:对于 webmagic 框架,您可以阅读以下讲义
5.1.代码结构
5.2.程序入口
Demo.java
/**
* 程序入口
*/
public class Demo {
public static void main(String[] args) {
// 爬取开始
Spider
// 爬取过程
.create(new WanhoPageProcessor())
// 爬取结果保存
.addPipeline(new WanhoPipeline())
// 爬取的第一个页面
.addUrl("http://www.wanho.net/a/jyxb/")
// 启用的线程数
.thread(5).run();
}
}
5.3.爬取过程
package net.wanho.wanhosite;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.processor.PageProcessor;
import us.codecraft.webmagic.selector.Html;
public class WanhoPageProcessor implements PageProcessor {
// 部分一:抓取网站的相关配置,包括编码、抓取间隔、重试次数等
private Site site = Site
.me()
.setTimeOut(10000)
.setRetryTimes(3)
.setSleepTime(1000)
.setCharset("UTF-8");
// 獲得站點
@Override
public Site getSite() {
return site;
}
//爬取過程
@Override
public void process(Page page) {
//获取当前页的所有喜报
List list = page.getHtml().xpath("//div[@class='main_l']/ul/li").all();
//要保存喜报的集合
Vector voLst = new Vector();
//遍历喜报
String title;
String content;
String img;
for (String item : list) {
Html tmp = Html.create(item);
//标题
title = tmp.xpath("//div[@class='content']/h4/a/text()").toString();
//内容
content = tmp.xpath("//div[@class='content']/p/text()").toString();
//图片路径
img = tmp.xpath("//a/img/@src").toString();
//加入集合
ArticleVo vo = new ArticleVo(title, content, img);
voLst.add(vo);
}
//保存数据至page中,后续进行持久化
page.putField("e_list", voLst);
//加载其它页
page.addTargetRequests( getOtherUrls());
}
//其它页
public List getOtherUrls(){
List urlLsts = new ArrayList();
for(int i=2;i网络选项),然后找到那些加载数据的json请求,最后直接请求那些URL获取数据来模拟浏览器请求,等待一个从满载开始的一定时间 只需从完成的页面中获取数据。这类爬虫通常需要内嵌浏览器内核,如:webmagic、phantom.js、HttpUnit等
接下来,我将通过我们的官网和大家一起分析一下如何实现这样的爬虫:
首先观察我们爬虫的起始页面是:
从上图可以看出,我们可以从首页的HTML源代码中直观的找到我们需要的标题、内容、图片链接等信息。那么我们可以通过什么方式提取这些目标数据呢?
其实提取页面元素的webmagic框架主要支持以下三种方法:
XPath 正则表达式 CSS 选择器
当然,选择哪种方式提取数据需要根据具体页面进行分析。在这个例子中,很明显使用XPath提取数据是最方便的
所以,那我直接给出我们需要爬取的数据的XPath路径:
注:“//”表示从相对路径开始,第一个“/”表示从页面路径开始;两个/后面的内容代表一个元素,括号内的内容表示该元素的执行属性,如:h1[@class='entry-title']表示:有一个h1元素,其class属性为“条目标题”
6.2.3. 页面数据提取:
使用webmagic提取页面数据时,需要自定义一个类来实现PageProcessor接口。
该类实现PageProcessor接口的主要功能如下三步:
爬虫配置:爬取页面的配置,包括编码、爬取间隔、重试次数等页面元素的提取:使用正则表达式或者XPath提取页面元素。新链接的发现:从一个页面找到的链接到其他待抓取的目标页面
<p>package net.wanho.wanhosite;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.processor.PageProcessor;
import us.codecraft.webmagic.selector.Html;
public class WanhoPageProcessor implements PageProcessor {
// 部分一:抓取网站的相关配置,包括编码、抓取间隔、重试次数等
private Site site = Site
.me()
.setTimeOut(10000)
.setRetryTimes(3)
.setSleepTime(1000)
.setCharset("UTF-8");
// 獲得站點
@Override
public Site getSite() {
return site;
}
//爬取過程
@Override
public void process(Page page) {
//获取当前页的所有喜报
List list = page.getHtml().xpath("//div[@class='main_l']/ul/li").all();
//要保存喜报的集合
Vector voLst = new Vector();
//遍历喜报
String title;
String content;
String img;
for (String item : list) {
Html tmp = Html.create(item);
//标题
title = tmp.xpath("//div[@class='content']/h4/a/text()").toString();
//内容
content = tmp.xpath("//div[@class='content']/p/text()").toString();
//图片路径
img = tmp.xpath("//a/img/@src").toString();
//加入集合
ArticleVo vo = new ArticleVo(title, content, img);
voLst.add(vo);
}
//保存数据至page中,后续进行持久化
page.putField("e_list", voLst);
//加载其它页
page.addTargetRequests( getOtherUrls());
}
//其它页
public List getOtherUrls(){
List urlLsts = new ArrayList();
for(int i=2;i
ajax抓取网页内容(ajax抓取网页内容的速度与很好的方法-苏州安嘉)
网站优化 • 优采云 发表了文章 • 0 个评论 • 43 次浏览 • 2021-12-31 13:00
ajax抓取网页内容。虽然加载的时间很长,但是在服务器可接受的情况下。这速度还是很好的。这应该算是对的起单价。直接使用网页内容,单价贵了很多。
对于纯粹的页面抓取scrapy是一个好选择。javascript样式加载,可以选择使用presetplus的preset文件或者sit+dom实现。
一楼的意思是只能在浏览器获取,那么:1.爬虫尽量只爬网页的相关结构,请求的文件,解析出来后再提交给后端处理。(做时间规划,把相关的时间分割来完成爬取的过程)2.如果你已经有数据库,直接在数据库取相关数据就行,在请求的时候解析它。3.如果手里没有数据库,那么采用分析对象来抓取(如links,findall,sitemaps等)对象动态变化太多,爬取成本高。
把你需要抓取的部分都放在数据库或是lib上,然后用xpath解析数据,
既然大家都同意用markdown,那么我就用markdown好了。
单纯为了抓取网页内容,单一的ajax抓取已经足够抓取速度快,反正你提交到服务器了,谁有空看你的js,css?我看到的大部分js,css服务器是可以解析的,比如那些网页上foo,bar,goto很多的,百度一下,你就知道。第二个问题是什么时候爬取?是抓取不着的东西吗?那么我的答案是,抓取不着的东西,如果没有时间限制的,在你有时间看的东西,都抓取下来,抓取着不着的东西,尽快丢掉。我并不支持再把什么文件之类的东西备份起来,所以也不存在什么时候发给客户的问题。 查看全部
ajax抓取网页内容(ajax抓取网页内容的速度与很好的方法-苏州安嘉)
ajax抓取网页内容。虽然加载的时间很长,但是在服务器可接受的情况下。这速度还是很好的。这应该算是对的起单价。直接使用网页内容,单价贵了很多。
对于纯粹的页面抓取scrapy是一个好选择。javascript样式加载,可以选择使用presetplus的preset文件或者sit+dom实现。
一楼的意思是只能在浏览器获取,那么:1.爬虫尽量只爬网页的相关结构,请求的文件,解析出来后再提交给后端处理。(做时间规划,把相关的时间分割来完成爬取的过程)2.如果你已经有数据库,直接在数据库取相关数据就行,在请求的时候解析它。3.如果手里没有数据库,那么采用分析对象来抓取(如links,findall,sitemaps等)对象动态变化太多,爬取成本高。
把你需要抓取的部分都放在数据库或是lib上,然后用xpath解析数据,
既然大家都同意用markdown,那么我就用markdown好了。
单纯为了抓取网页内容,单一的ajax抓取已经足够抓取速度快,反正你提交到服务器了,谁有空看你的js,css?我看到的大部分js,css服务器是可以解析的,比如那些网页上foo,bar,goto很多的,百度一下,你就知道。第二个问题是什么时候爬取?是抓取不着的东西吗?那么我的答案是,抓取不着的东西,如果没有时间限制的,在你有时间看的东西,都抓取下来,抓取着不着的东西,尽快丢掉。我并不支持再把什么文件之类的东西备份起来,所以也不存在什么时候发给客户的问题。
ajax抓取网页内容(关于百度搜索引擎工作原理知识,有不少站长SEO还没有)
网站优化 • 优采云 发表了文章 • 0 个评论 • 69 次浏览 • 2021-12-30 15:01
关于百度搜索引擎的工作原理,很多站长都没有仔细阅读和理解SEO。本文讲解了百度蜘蛛爬取系统的原理和索引构建,让SEOer对百度蜘蛛的索引构建有更多的了解。
一、Spider抓取系统的基本框架
互联网信息的爆炸式增长,如何有效地获取和使用这些信息是搜索引擎工作中最重要的环节。数据采集系统作为整个搜索系统的上游,主要负责互联网信息的采集、保存和更新。它像蜘蛛一样在网络中爬行,所以通常被称为“蜘蛛”。比如我们常用的几种常见的搜索引擎蜘蛛叫做:Baiduspdier、Googlebot、搜狗网蜘蛛等。
蜘蛛爬取系统是搜索引擎数据来源的重要保障。如果把网络理解为一个有向图,那么蜘蛛的工作过程可以看作是对这个有向图的一次遍历。从一些重要的种子网址开始,通过页面上的超链接,不断地发现和抓取新的网址,尽可能多地抓取有价值的网页。对于像百度这样的大型蜘蛛系统,由于网页随时都有可能被修改、删除或出现新的超链接,所以需要更新以前蜘蛛爬过的页面,并维护一个URL库和页面库.
下图为蜘蛛爬取系统的基本框架,包括链接存储系统、链接选择系统、dns解析服务系统、爬取调度系统、网页分析系统、链接提取系统、链接分析系统、网页存储系统. 百度蜘蛛通过本系统的配合完成对网页的抓取。
二、百度蜘蛛的主要爬取策略类型
上图看似简单,但Baiduspider在爬取过程中实际上面临着一个超级复杂的网络环境,为了让系统尽可能多的抓取有价值的资源,并保持页面在系统和实际环境中的一致性在同时不会给网站体验带来压力,会设计出多种复杂的爬取策略。以下是简要介绍:
1. 抓取友好
互联网资源的巨大数量级要求抓取系统尽可能高效地使用带宽,在有限的硬件和带宽资源下抓取尽可能多的有价值的资源。这就产生了另一个问题。抓取网站的带宽消耗造成访问压力。如果度数过大,将直接影响抓取网站的正常用户访问行为。因此,在爬取过程中,必须控制一定的爬取压力,以达到不影响用户正常访问网站,抓取尽可能多的有价值资源的目的。
通常,最基本的是基于ip的压力控制。这是因为如果是基于一个域名,可能会出现一个域名对应多个ip(很多大网站)或者多个域名对应同一个ip(小网站共享ip)的问题。在实际中,压力部署控制往往是根据ip和域名的各种情况进行的。同时,站长平台也推出了压力反馈工具。站长可以手动调整自己网站的爬虫压力。此时,百度蜘蛛会根据站长的要求,优先进行爬取压力控制。
同一个站点的抓取速度控制一般分为两类:一类是一段时间内的抓取频率;二是一段时间内的爬取流量。同一个站点的爬取速度在不同的时间会有所不同。例如,在夜晚安静、月亮暗、风大的时候,爬行速度可能会更快。它还取决于特定的站点类型。主要思想是错开正常用户访问的高峰期,不断调整。对于不同的站点,也需要不同的爬取速度。
3、新链接重要性的判断
在建库链接之前,百度蜘蛛会对页面进行初步的内容分析和链接分析,通过内容分析判断网页是否需要建索引库,通过链接分析找到更多的网页,然后抓取更多的网页——分析——是否建库&发现新链接的过程。理论上,百度蜘蛛会检索新页面上所有可以“看到”的链接。那么,面对众多的新链接,百度蜘蛛是根据什么判断哪个更重要呢?两个方面:
首先,对用户的价值是独一无二的。百度搜索引擎喜欢独特的内容突出。不要因为网页的主要内容不突出而被搜索引擎误判为空页和短页。其次,链接很重要。目录级别-站点中浅优先链接的流行度
四、百度优先建设重要图书馆的原则
百度蜘蛛抓取的页面数量并不是最重要的。重要的是一个索引数据库建了多少页,也就是我们常说的“建库”。众所周知,搜索引擎的索引库是分层的。优质的网页会被分配到重要的索引库,普通的网页会留在普通的图书馆,更糟糕的网页会被分配到低级别的图书馆作为补充资料。目前60%的搜索需求只需要调用重要的索引库就可以满足,这也解释了为什么有些网站流量极高却一直不尽人意的原因。
那么,哪些网页可以进入优质索引库呢?其实总的原则是一个:对用户有价值。包括但不仅限于:
及时性和有价值的页面:在这里,及时性和价值并存,缺一不可。有些网站为了生成时间敏感的内容页面,做了大量的采集工作,产生了一堆毫无价值的页面,百度不想看到。优质专题页:专题页内容不一定完全原创,也可以很好的整合各方内容,或者添加一些新鲜的内容,如意见、评论等,为用户提供更丰富、更多的内容内容全面。高价值原创内容页面:百度将原创定义为经过一定成本和大量经验形成的文章。不要问我们伪原创是不是原创。重要的个人页面:这里只是一个例子。科比已经在新浪微博上开设了一个账户。就算他不经常更新,对百度来说也是极其重要的一个页面。5、哪些网页不能建索引库
上述优质网页都被收录在索引库中,但实际上,互联网上的大多数网站根本没有被百度收录。不是百度没找到,而是建库前的筛选链接被过滤掉了。那么一开始过滤掉了什么样的网页:
内容重复的网页:百度无需收录
互联网上已有的内容。主要内容较短的网页使用了百度蜘蛛无法解析的技术,如JS、AJAX等,虽然用户访问时可以看到丰富的内容,但仍会被搜索引擎丢弃。加载速度较慢的网页也可用作将短页面视为空白。请注意,广告的加载时间计为网页的整体加载时间。很多主体不突出的网页,即使被爬回来,也会在这个链接中被丢弃。一些作弊页面
更多关于aiduspider爬取系统原理和索引构建,请到百度站长论坛查看文档。
这篇文章就到此为止,希望能给大家带来一些思考。想学习更多SEO专业知识,可以关注微信公众号:“爱学SEO”,阅读好文章和优质教学视频。 查看全部
ajax抓取网页内容(关于百度搜索引擎工作原理知识,有不少站长SEO还没有)
关于百度搜索引擎的工作原理,很多站长都没有仔细阅读和理解SEO。本文讲解了百度蜘蛛爬取系统的原理和索引构建,让SEOer对百度蜘蛛的索引构建有更多的了解。
一、Spider抓取系统的基本框架
互联网信息的爆炸式增长,如何有效地获取和使用这些信息是搜索引擎工作中最重要的环节。数据采集系统作为整个搜索系统的上游,主要负责互联网信息的采集、保存和更新。它像蜘蛛一样在网络中爬行,所以通常被称为“蜘蛛”。比如我们常用的几种常见的搜索引擎蜘蛛叫做:Baiduspdier、Googlebot、搜狗网蜘蛛等。
蜘蛛爬取系统是搜索引擎数据来源的重要保障。如果把网络理解为一个有向图,那么蜘蛛的工作过程可以看作是对这个有向图的一次遍历。从一些重要的种子网址开始,通过页面上的超链接,不断地发现和抓取新的网址,尽可能多地抓取有价值的网页。对于像百度这样的大型蜘蛛系统,由于网页随时都有可能被修改、删除或出现新的超链接,所以需要更新以前蜘蛛爬过的页面,并维护一个URL库和页面库.
下图为蜘蛛爬取系统的基本框架,包括链接存储系统、链接选择系统、dns解析服务系统、爬取调度系统、网页分析系统、链接提取系统、链接分析系统、网页存储系统. 百度蜘蛛通过本系统的配合完成对网页的抓取。
二、百度蜘蛛的主要爬取策略类型
上图看似简单,但Baiduspider在爬取过程中实际上面临着一个超级复杂的网络环境,为了让系统尽可能多的抓取有价值的资源,并保持页面在系统和实际环境中的一致性在同时不会给网站体验带来压力,会设计出多种复杂的爬取策略。以下是简要介绍:
1. 抓取友好
互联网资源的巨大数量级要求抓取系统尽可能高效地使用带宽,在有限的硬件和带宽资源下抓取尽可能多的有价值的资源。这就产生了另一个问题。抓取网站的带宽消耗造成访问压力。如果度数过大,将直接影响抓取网站的正常用户访问行为。因此,在爬取过程中,必须控制一定的爬取压力,以达到不影响用户正常访问网站,抓取尽可能多的有价值资源的目的。
通常,最基本的是基于ip的压力控制。这是因为如果是基于一个域名,可能会出现一个域名对应多个ip(很多大网站)或者多个域名对应同一个ip(小网站共享ip)的问题。在实际中,压力部署控制往往是根据ip和域名的各种情况进行的。同时,站长平台也推出了压力反馈工具。站长可以手动调整自己网站的爬虫压力。此时,百度蜘蛛会根据站长的要求,优先进行爬取压力控制。
同一个站点的抓取速度控制一般分为两类:一类是一段时间内的抓取频率;二是一段时间内的爬取流量。同一个站点的爬取速度在不同的时间会有所不同。例如,在夜晚安静、月亮暗、风大的时候,爬行速度可能会更快。它还取决于特定的站点类型。主要思想是错开正常用户访问的高峰期,不断调整。对于不同的站点,也需要不同的爬取速度。

3、新链接重要性的判断
在建库链接之前,百度蜘蛛会对页面进行初步的内容分析和链接分析,通过内容分析判断网页是否需要建索引库,通过链接分析找到更多的网页,然后抓取更多的网页——分析——是否建库&发现新链接的过程。理论上,百度蜘蛛会检索新页面上所有可以“看到”的链接。那么,面对众多的新链接,百度蜘蛛是根据什么判断哪个更重要呢?两个方面:
首先,对用户的价值是独一无二的。百度搜索引擎喜欢独特的内容突出。不要因为网页的主要内容不突出而被搜索引擎误判为空页和短页。其次,链接很重要。目录级别-站点中浅优先链接的流行度

四、百度优先建设重要图书馆的原则
百度蜘蛛抓取的页面数量并不是最重要的。重要的是一个索引数据库建了多少页,也就是我们常说的“建库”。众所周知,搜索引擎的索引库是分层的。优质的网页会被分配到重要的索引库,普通的网页会留在普通的图书馆,更糟糕的网页会被分配到低级别的图书馆作为补充资料。目前60%的搜索需求只需要调用重要的索引库就可以满足,这也解释了为什么有些网站流量极高却一直不尽人意的原因。
那么,哪些网页可以进入优质索引库呢?其实总的原则是一个:对用户有价值。包括但不仅限于:
及时性和有价值的页面:在这里,及时性和价值并存,缺一不可。有些网站为了生成时间敏感的内容页面,做了大量的采集工作,产生了一堆毫无价值的页面,百度不想看到。优质专题页:专题页内容不一定完全原创,也可以很好的整合各方内容,或者添加一些新鲜的内容,如意见、评论等,为用户提供更丰富、更多的内容内容全面。高价值原创内容页面:百度将原创定义为经过一定成本和大量经验形成的文章。不要问我们伪原创是不是原创。重要的个人页面:这里只是一个例子。科比已经在新浪微博上开设了一个账户。就算他不经常更新,对百度来说也是极其重要的一个页面。5、哪些网页不能建索引库
上述优质网页都被收录在索引库中,但实际上,互联网上的大多数网站根本没有被百度收录。不是百度没找到,而是建库前的筛选链接被过滤掉了。那么一开始过滤掉了什么样的网页:
内容重复的网页:百度无需收录
互联网上已有的内容。主要内容较短的网页使用了百度蜘蛛无法解析的技术,如JS、AJAX等,虽然用户访问时可以看到丰富的内容,但仍会被搜索引擎丢弃。加载速度较慢的网页也可用作将短页面视为空白。请注意,广告的加载时间计为网页的整体加载时间。很多主体不突出的网页,即使被爬回来,也会在这个链接中被丢弃。一些作弊页面
更多关于aiduspider爬取系统原理和索引构建,请到百度站长论坛查看文档。
这篇文章就到此为止,希望能给大家带来一些思考。想学习更多SEO专业知识,可以关注微信公众号:“爱学SEO”,阅读好文章和优质教学视频。
ajax抓取网页内容(【Python之Ajax数据爬取】照Web发展的趋势)
网站优化 • 优采云 发表了文章 • 0 个评论 • 47 次浏览 • 2021-12-27 04:21
Python 的 Ajax 数据爬网介绍
有时我们使用requests获取网页时,得到的结果可能与浏览器中看到的不同:在浏览器中可以看到正常显示的页面数据,但是使用requests获取的结果却看不到。
这是因为请求获取的数据都是原创
HTML文档,浏览器中的页面是JavaScript处理数据后生成的结果。这些数据的来源有很多,可能是通过Ajax加载的,也可能是收录
在HTML文档中,也可能是通过JavaScript和特定算法计算后生成的。
对于第一种情况,数据加载是一种异步加载方式。原创
页面最初不会收录
一些数据。原创
页面加载完毕后,会请求一个接口,从服务器获取数据,然后将数据进行处理,呈现在网页上,这其实就是一个ajax请求。
根据Web的发展趋势,这种形式的页面越来越多。网页的原创
HTML 文档不收录
任何数据。数据通过Ajax统一加载后呈现,使得Web开发中的左前后端分离,减少了服务器直接渲染页面的压力。
所以如果遇到这样的页面,可以直接使用requests等库来抓取原创
网页,无法获取有效数据。这时候就需要从网页后台分析发送到界面的Ajax请求。如果可以使用requests来模拟ajax请求,那么就可以爬取成功。
什么是阿贾克斯?
Ajax,全称Asynchronous JavaScript and XML,即异步JavaScript和XML。它不是一种编程语言,而是一种使用 JavaScript 与服务器交换数据并更新部分网页的技术,同时确保页面不会被刷新,页面链接不会发生变化。
对于传统网页,如果要更新其内容,必须刷新整个页面,而使用Ajax,可以在不刷新页面的情况下更新其内容。在这个过程中,页面实际上是在后台与服务器进行交互。获取到数据后,通过JavaScript来改变网页,从而更新网页的内容。
1.实例介绍
在浏览网页时,我们会发现很多网页都有向下滚动查看更多选项。比如下面这个腾讯新闻网站一直在下降,可以发现,下降了几个新闻之后,就不再下线了。相反,将出现加载动画。一段时间后,新的新闻内容将继续出现在下方。这个过程其实就是Ajax加载的过程。
我们注意到页面没有完全刷新,这意味着页面上的链接没有改变,但页面上有更多的新内容,也就是后来发布的新消息。这是获取新数据并通过 Ajax 呈现的过程。
2.基本原则
初步了解了 Ajax 之后,我们再来了解一下它的基本原理。向网页更新发送ajax请求的过程可以简单分为以下3个步骤:
(1) 发送请求;
(2)分析内容;
(3) 渲染网页。 查看全部
ajax抓取网页内容(【Python之Ajax数据爬取】照Web发展的趋势)
Python 的 Ajax 数据爬网介绍
有时我们使用requests获取网页时,得到的结果可能与浏览器中看到的不同:在浏览器中可以看到正常显示的页面数据,但是使用requests获取的结果却看不到。
这是因为请求获取的数据都是原创
HTML文档,浏览器中的页面是JavaScript处理数据后生成的结果。这些数据的来源有很多,可能是通过Ajax加载的,也可能是收录
在HTML文档中,也可能是通过JavaScript和特定算法计算后生成的。
对于第一种情况,数据加载是一种异步加载方式。原创
页面最初不会收录
一些数据。原创
页面加载完毕后,会请求一个接口,从服务器获取数据,然后将数据进行处理,呈现在网页上,这其实就是一个ajax请求。
根据Web的发展趋势,这种形式的页面越来越多。网页的原创
HTML 文档不收录
任何数据。数据通过Ajax统一加载后呈现,使得Web开发中的左前后端分离,减少了服务器直接渲染页面的压力。
所以如果遇到这样的页面,可以直接使用requests等库来抓取原创
网页,无法获取有效数据。这时候就需要从网页后台分析发送到界面的Ajax请求。如果可以使用requests来模拟ajax请求,那么就可以爬取成功。
什么是阿贾克斯?
Ajax,全称Asynchronous JavaScript and XML,即异步JavaScript和XML。它不是一种编程语言,而是一种使用 JavaScript 与服务器交换数据并更新部分网页的技术,同时确保页面不会被刷新,页面链接不会发生变化。
对于传统网页,如果要更新其内容,必须刷新整个页面,而使用Ajax,可以在不刷新页面的情况下更新其内容。在这个过程中,页面实际上是在后台与服务器进行交互。获取到数据后,通过JavaScript来改变网页,从而更新网页的内容。
1.实例介绍
在浏览网页时,我们会发现很多网页都有向下滚动查看更多选项。比如下面这个腾讯新闻网站一直在下降,可以发现,下降了几个新闻之后,就不再下线了。相反,将出现加载动画。一段时间后,新的新闻内容将继续出现在下方。这个过程其实就是Ajax加载的过程。

我们注意到页面没有完全刷新,这意味着页面上的链接没有改变,但页面上有更多的新内容,也就是后来发布的新消息。这是获取新数据并通过 Ajax 呈现的过程。
2.基本原则
初步了解了 Ajax 之后,我们再来了解一下它的基本原理。向网页更新发送ajax请求的过程可以简单分为以下3个步骤:
(1) 发送请求;
(2)分析内容;
(3) 渲染网页。
ajax抓取网页内容(Pythonselenium3.14为什么selenium不能直接拦截请求呢?(图))
网站优化 • 优采云 发表了文章 • 0 个评论 • 55 次浏览 • 2021-12-27 00:04
部门需要一个自动化脚本来完成web端接口功能的冒烟,需要在页面加载时抓取ajax请求,从接口层面判断请求是否成功。查阅了大量资料,没有人有处理相关问题的经验,过程中坑也很多,所以如果你也有这个需求,继续往下看吧~
环境和语言:
Python
硒3.14
为什么selenium不能直接拦截请求体?这是Chrome官方故意做的。详情请参考此网址:
%20response%20body&can=1
在网上搜索后,找到了三种解决方法:
1、 取代理,拦截代理级别的日志请求;如果proxy过期了,请求会变得很慢,所以没有采用,有需要的可以自己研究。
2、使用硒线。这是 GitHub 上的一个开源项目。可以直接拦截response_code和body。原理大概就是看源码了。它也应该是一个代理,但这个项目是为你打包的。
当时看到真的很激动,所有的问题都通过pip install解决了。但是当我怀着极大的兴趣运行代码时,发现网页报错:err_proxy_connection_failed。感觉莫名其妙,跑到开源项目中寻找答案。这不仅发生在我身上,也可以说是这个开源项目的一个bug。到目前为止还没有关闭。我很久没有放弃调试,但是这条路走不通,只好流泪放弃。事实证明,不要只相信一颗星星只有一两百颗星星。开源代码放在下面,万一你能通过:
3、开启selenium性能捕获,可以在性能日志中进行修改拦截response_body:
先总结一下总体思路:
结合selenium和Chrome devtool:selenium可以打开性能日志,根据性能日志中的Network.responseReceived事件抓取requestId和对应的url,然后结合selenium提供的execute方法传入requestId参数来获取相应的身体反应。
execute_cdp_cmd()方法的源码里有例子,讲的很清楚,可以去看看。本文还将给出代码示例:
1 caps = DesiredCapabilities.CHROME
2 caps['goog:loggingPrefs'] = {'performance': 'ALL'}
3
4 def driver():
5 global driver
6 driver = webdriver.Chrome(desired_capabilities=caps)
7 driver.maximize_window()
请注意第二行代码,这是我踩到的第一个坑:
很多教程中给出的代码如下:
caps['loggingPrefs'] = {'performance':'ALL'},用这段代码打开性能日志,但是这样运行会报错,原因来自chromedriver,75.< @k27@从>3770.8开始,一定要这样运行。
注意只打开性能日志还是不能抓到正文。如果你的需求只是判断状态码,那么上面的方案就足够了。
1、为什么需要获取requestid:
Chrome性能日志的获取需要配合Chrome DevTool方法使用。本文档详细列出了 Chrome 提供的域。在域网络下,您可以选择所需的方法:
在这里,我选择了我需要的方法,如下图所示,可以看到,这里需要传入一个名为requestId的参数,它是唯一的请求ID,当我们可以抓取到我们想要的body时我们明白了。但我从未听说过这个 requestId。我可以从哪里得到它?这时候就需要对抓取到的性能日志中的事件进行分析。
2、 关于Chrome返回的日志事件,可以参与这个博客,里面有详细的介绍。基于这个博客(.),我分析了我要使用的事件-Network.responseReceived,其中收录
requestid。返回值。
1 def parse_response_body(driver):
2 """获取requestid"""
3 browser_log = driver.get_log('performance')
4 events = [_process_browser_log_entry(entry) for entry in browser_log]
5 events_response = [event for event in events if 'Network.responseReceived' == event['method']] # 根据Network.responseReceived这个network,解析出requestId
6 for res in events_response:
7 requestId = res["params"]["requestId"]
3、总结一下,结合selenium中的方法:
1 def execute_cdp_cmd(driver, cmd, cmd_args):
2 return driver.execute("executeCdpCommand", {'cmd': cmd, 'params': cmd_args})['value']
3
4
5 response_body = driver.execute_cdp_cmd('Network.getResponseBody', {'requestId': requestId}
接下来就很简单了,抓取body,然后用json解析。就在我满怀信心的时候,现实又给了我沉重的一击。在抓取请求体的过程中,程序报错。
未找到具有给定标识符的资源
这是我踩过的最大的坑。它困扰了我五六个小时。我以为是我的代码有问题。一直在调试,在网上找问题,最后在一篇不太相关的js博客里。对于这句话:getResponseBody will error发生在查询什么都不返回时...
回到界面,手动获取了当前运行页面的ajax请求,结果都是没有返回体的请求ORZ。
果断地尝试……除了……,然后程序运行得很漂亮!此刻的心情真是激动的想哭。
后记:
这种需求感觉很普遍。毕竟界面元素能不能加载成功,是看界面返回最直接可靠的方式,但是不知道为什么国内好像没有相关的博客(可能是我没有搜索过了)。所以想记录下这篇文章,希望有需要的朋友不要走那么多弯路,轻松解决问题~~
PS:在FQ的过程中,我也找到了将selenium升级到4的方案,因为selenium 4开始和Chrome DevTools一起支持收购了。但是,只找到了 Java 示例。因为对Java不是很熟悉,所以被抛弃了。他们在这里为每个人提供。如果你需要它,你可以拿起它:
@ohanaadi/chrome-devtools-and-selenium-4-eadab5d755b7
-----------------------我是分割线 2021/02/01----------------- - ---------
今天在看技术博客的时候发现了一个开源项目,是一个被proxy拦截的ajax请求。先记录一下信息: 查看全部
ajax抓取网页内容(Pythonselenium3.14为什么selenium不能直接拦截请求呢?(图))
部门需要一个自动化脚本来完成web端接口功能的冒烟,需要在页面加载时抓取ajax请求,从接口层面判断请求是否成功。查阅了大量资料,没有人有处理相关问题的经验,过程中坑也很多,所以如果你也有这个需求,继续往下看吧~
环境和语言:
Python
硒3.14
为什么selenium不能直接拦截请求体?这是Chrome官方故意做的。详情请参考此网址:
%20response%20body&can=1
在网上搜索后,找到了三种解决方法:
1、 取代理,拦截代理级别的日志请求;如果proxy过期了,请求会变得很慢,所以没有采用,有需要的可以自己研究。
2、使用硒线。这是 GitHub 上的一个开源项目。可以直接拦截response_code和body。原理大概就是看源码了。它也应该是一个代理,但这个项目是为你打包的。
当时看到真的很激动,所有的问题都通过pip install解决了。但是当我怀着极大的兴趣运行代码时,发现网页报错:err_proxy_connection_failed。感觉莫名其妙,跑到开源项目中寻找答案。这不仅发生在我身上,也可以说是这个开源项目的一个bug。到目前为止还没有关闭。我很久没有放弃调试,但是这条路走不通,只好流泪放弃。事实证明,不要只相信一颗星星只有一两百颗星星。开源代码放在下面,万一你能通过:
3、开启selenium性能捕获,可以在性能日志中进行修改拦截response_body:
先总结一下总体思路:
结合selenium和Chrome devtool:selenium可以打开性能日志,根据性能日志中的Network.responseReceived事件抓取requestId和对应的url,然后结合selenium提供的execute方法传入requestId参数来获取相应的身体反应。
execute_cdp_cmd()方法的源码里有例子,讲的很清楚,可以去看看。本文还将给出代码示例:
1 caps = DesiredCapabilities.CHROME
2 caps['goog:loggingPrefs'] = {'performance': 'ALL'}
3
4 def driver():
5 global driver
6 driver = webdriver.Chrome(desired_capabilities=caps)
7 driver.maximize_window()
请注意第二行代码,这是我踩到的第一个坑:
很多教程中给出的代码如下:
caps['loggingPrefs'] = {'performance':'ALL'},用这段代码打开性能日志,但是这样运行会报错,原因来自chromedriver,75.< @k27@从>3770.8开始,一定要这样运行。
注意只打开性能日志还是不能抓到正文。如果你的需求只是判断状态码,那么上面的方案就足够了。
1、为什么需要获取requestid:
Chrome性能日志的获取需要配合Chrome DevTool方法使用。本文档详细列出了 Chrome 提供的域。在域网络下,您可以选择所需的方法:
在这里,我选择了我需要的方法,如下图所示,可以看到,这里需要传入一个名为requestId的参数,它是唯一的请求ID,当我们可以抓取到我们想要的body时我们明白了。但我从未听说过这个 requestId。我可以从哪里得到它?这时候就需要对抓取到的性能日志中的事件进行分析。

2、 关于Chrome返回的日志事件,可以参与这个博客,里面有详细的介绍。基于这个博客(.),我分析了我要使用的事件-Network.responseReceived,其中收录
requestid。返回值。
1 def parse_response_body(driver):
2 """获取requestid"""
3 browser_log = driver.get_log('performance')
4 events = [_process_browser_log_entry(entry) for entry in browser_log]
5 events_response = [event for event in events if 'Network.responseReceived' == event['method']] # 根据Network.responseReceived这个network,解析出requestId
6 for res in events_response:
7 requestId = res["params"]["requestId"]
3、总结一下,结合selenium中的方法:
1 def execute_cdp_cmd(driver, cmd, cmd_args):
2 return driver.execute("executeCdpCommand", {'cmd': cmd, 'params': cmd_args})['value']
3
4
5 response_body = driver.execute_cdp_cmd('Network.getResponseBody', {'requestId': requestId}
接下来就很简单了,抓取body,然后用json解析。就在我满怀信心的时候,现实又给了我沉重的一击。在抓取请求体的过程中,程序报错。
未找到具有给定标识符的资源
这是我踩过的最大的坑。它困扰了我五六个小时。我以为是我的代码有问题。一直在调试,在网上找问题,最后在一篇不太相关的js博客里。对于这句话:getResponseBody will error发生在查询什么都不返回时...
回到界面,手动获取了当前运行页面的ajax请求,结果都是没有返回体的请求ORZ。
果断地尝试……除了……,然后程序运行得很漂亮!此刻的心情真是激动的想哭。
后记:
这种需求感觉很普遍。毕竟界面元素能不能加载成功,是看界面返回最直接可靠的方式,但是不知道为什么国内好像没有相关的博客(可能是我没有搜索过了)。所以想记录下这篇文章,希望有需要的朋友不要走那么多弯路,轻松解决问题~~
PS:在FQ的过程中,我也找到了将selenium升级到4的方案,因为selenium 4开始和Chrome DevTools一起支持收购了。但是,只找到了 Java 示例。因为对Java不是很熟悉,所以被抛弃了。他们在这里为每个人提供。如果你需要它,你可以拿起它:
@ohanaadi/chrome-devtools-and-selenium-4-eadab5d755b7
-----------------------我是分割线 2021/02/01----------------- - ---------
今天在看技术博客的时候发现了一个开源项目,是一个被proxy拦截的ajax请求。先记录一下信息:
ajax抓取网页内容(FacebookWard的解决方法及解决办法)
网站优化 • 优采云 发表了文章 • 0 个评论 • 56 次浏览 • 2021-12-26 18:09
大家在浏览Facebook相册的时候有没有注意到,页面部分刷新时地址栏中的地址也发生了变化,并不是hash方法。它使用了 HTML5 历史上的几个新 API。作为窗口的全局变量,历史在 HTML4 时代并不是什么新鲜事。我们经常使用 history.back() 和 history.go()。
一直觉得没办法,直到两天前看到Discourse创始人之一Robin Ward的解决方案,忍不住尖叫起来。
Discourse 是一个严重依赖 Ajax 的论坛程序,但它必须被 Google 收录。它的解决方案是放弃hash结构,使用History API。
所谓History API,就是在不刷新页面的情况下,改变浏览器地址栏中显示的URL(准确的说是改变网页的当前状态)。这是一个示例,您单击上面的按钮开始播放音乐。然后,点击下面的链接看看发生了什么?
地址栏中的网址已更改,但音乐播放并未中断!
对 History API 的详细介绍超出了本文的范围。简单的说到这里,它的作用就是给浏览器的History对象添加一条记录。
window.history.pushState(state object, title, url);
上面这行命令可以让地址栏中出现一个新的 URL。History对象的pushState方法接受三个参数,新的URL为第三个参数,前两个参数可以为null。
window.history.pushState(null, null, newURL);
目前主流浏览器都支持这种方式:Chrome(26.0+)、Firefox(20.0+)、IE(10.0+)、Safari(5.1+)、歌剧 (12.1+)。
这是罗宾沃德的方法。
首先用History API替换hash结构,让每一个hash符号变成一个正常路径的URL,这样搜索引擎就会抓取每一个网页。
/1
/2
/3
然后,定义一个 JavaScript 函数来处理 Ajax 部分并根据 URL 抓取内容(假设使用 jQuery)。
function anchorClick(link) {
var linkSplit = link.split('/').pop();
$.get('api/' + linkSplit, function(data) {
$('#content').html(data);
});
}
然后定义鼠标的点击事件。
$('#container').on('click', 'a', function(e) {
window.history.pushState(null, null, $(this).attr('href'));
anchorClick($(this).attr('href'));
e.preventDefault();
});
还要考虑用户点击浏览器的“前进/后退”按钮。这时候会触发History对象的popstate事件。
window.addEventListener('popstate', function(e) {
anchorClick(location.pathname);
});
定义以上三段代码后,无需刷新页面即可显示正常路径URL和AJAX内容。
最后,设置服务器端。
因为没有使用 hashtag 结构,所以每个 URL 都是不同的请求。因此,服务器需要向所有这些请求返回具有以下结构的网页,以防止 404 错误。
... ...
如果你仔细看上面的代码,你会发现里面有一个 noscript 标签。这就是秘密。
我们将所有要被搜索引擎收录的内容放在 noscript 标签中。在这种情况下,用户仍然可以在不刷新页面的情况下执行 AJAX 操作,但是搜索引擎会收录
每个页面的主要内容! 查看全部
ajax抓取网页内容(FacebookWard的解决方法及解决办法)
大家在浏览Facebook相册的时候有没有注意到,页面部分刷新时地址栏中的地址也发生了变化,并不是hash方法。它使用了 HTML5 历史上的几个新 API。作为窗口的全局变量,历史在 HTML4 时代并不是什么新鲜事。我们经常使用 history.back() 和 history.go()。
一直觉得没办法,直到两天前看到Discourse创始人之一Robin Ward的解决方案,忍不住尖叫起来。

Discourse 是一个严重依赖 Ajax 的论坛程序,但它必须被 Google 收录。它的解决方案是放弃hash结构,使用History API。
所谓History API,就是在不刷新页面的情况下,改变浏览器地址栏中显示的URL(准确的说是改变网页的当前状态)。这是一个示例,您单击上面的按钮开始播放音乐。然后,点击下面的链接看看发生了什么?

地址栏中的网址已更改,但音乐播放并未中断!
对 History API 的详细介绍超出了本文的范围。简单的说到这里,它的作用就是给浏览器的History对象添加一条记录。
window.history.pushState(state object, title, url);
上面这行命令可以让地址栏中出现一个新的 URL。History对象的pushState方法接受三个参数,新的URL为第三个参数,前两个参数可以为null。
window.history.pushState(null, null, newURL);
目前主流浏览器都支持这种方式:Chrome(26.0+)、Firefox(20.0+)、IE(10.0+)、Safari(5.1+)、歌剧 (12.1+)。
这是罗宾沃德的方法。
首先用History API替换hash结构,让每一个hash符号变成一个正常路径的URL,这样搜索引擎就会抓取每一个网页。
/1
/2
/3
然后,定义一个 JavaScript 函数来处理 Ajax 部分并根据 URL 抓取内容(假设使用 jQuery)。
function anchorClick(link) {
var linkSplit = link.split('/').pop();
$.get('api/' + linkSplit, function(data) {
$('#content').html(data);
});
}
然后定义鼠标的点击事件。
$('#container').on('click', 'a', function(e) {
window.history.pushState(null, null, $(this).attr('href'));
anchorClick($(this).attr('href'));
e.preventDefault();
});
还要考虑用户点击浏览器的“前进/后退”按钮。这时候会触发History对象的popstate事件。
window.addEventListener('popstate', function(e) {
anchorClick(location.pathname);
});
定义以上三段代码后,无需刷新页面即可显示正常路径URL和AJAX内容。
最后,设置服务器端。
因为没有使用 hashtag 结构,所以每个 URL 都是不同的请求。因此,服务器需要向所有这些请求返回具有以下结构的网页,以防止 404 错误。
... ...
如果你仔细看上面的代码,你会发现里面有一个 noscript 标签。这就是秘密。
我们将所有要被搜索引擎收录的内容放在 noscript 标签中。在这种情况下,用户仍然可以在不刷新页面的情况下执行 AJAX 操作,但是搜索引擎会收录
每个页面的主要内容!
ajax抓取网页内容(程序中使用functionGetHtml获得的网页源码中并不会更新内容)
网站优化 • 优采云 发表了文章 • 0 个评论 • 62 次浏览 • 2021-12-21 23:06
使用程序中的TWebbrowser控件或Indy中的控件使用Ajax技术连接网页,获取的网页源代码不会收录任何客户端更新。同理,在IE浏览器中查看源文件时也看不到Ajax更新的内容。通过插件可以看到Ajax的更新内容。问题是如何在程序中获取完整的网页内容?
如果有 Ajax 更新,则不会触发 Webbrowser 的 DocumentComplete 事件。
其实,完整的网页内容并非不可用,只需使用一个简单的方法:
函数 GetHtml(const WebBrowser:TWebBrowser): 字符串;
无功
文档:IHTMLDocument2;
开始
Doc := WebBrowser.Document as IHTMLDocument2;
如果已分配(Doc) 和已分配(Doc.body) 那么
结果:= Doc.body.OuterHtml; //也可以使用innerHTML来获取它的HTML文本
结尾;
这样得到的HTML内容收录了Ajax更新的内容。
现在关键是没有什么好的方法可以判断Ajax是否更新了,因为是异步更新,所以判断起来比较困难。我在互联网上搜索。国外好像有更复杂的解决方案,我也没有研究过是否可行。
我做过网页内容采集软件,不知道有没有好的处理方法,欢迎指教。:-) 查看全部
ajax抓取网页内容(程序中使用functionGetHtml获得的网页源码中并不会更新内容)
使用程序中的TWebbrowser控件或Indy中的控件使用Ajax技术连接网页,获取的网页源代码不会收录任何客户端更新。同理,在IE浏览器中查看源文件时也看不到Ajax更新的内容。通过插件可以看到Ajax的更新内容。问题是如何在程序中获取完整的网页内容?
如果有 Ajax 更新,则不会触发 Webbrowser 的 DocumentComplete 事件。
其实,完整的网页内容并非不可用,只需使用一个简单的方法:
函数 GetHtml(const WebBrowser:TWebBrowser): 字符串;
无功
文档:IHTMLDocument2;
开始
Doc := WebBrowser.Document as IHTMLDocument2;
如果已分配(Doc) 和已分配(Doc.body) 那么
结果:= Doc.body.OuterHtml; //也可以使用innerHTML来获取它的HTML文本
结尾;
这样得到的HTML内容收录了Ajax更新的内容。
现在关键是没有什么好的方法可以判断Ajax是否更新了,因为是异步更新,所以判断起来比较困难。我在互联网上搜索。国外好像有更复杂的解决方案,我也没有研究过是否可行。
我做过网页内容采集软件,不知道有没有好的处理方法,欢迎指教。:-)
ajax抓取网页内容(越来越+感叹号的解决方法放弃井号结构的url结构)
网站优化 • 优采云 发表了文章 • 0 个评论 • 50 次浏览 • 2021-12-21 01:09
越来越多的网站开始采用“单页应用”。
整个网站只有一个网页,使用ajax技术根据用户的输入加载不同的内容。
这种方式的优点是用户体验好,节省流量。缺点是ajax内容无法被搜索引擎抓取。例如,您有一个 网站。
http://www.51sjk.com/Upload/Ar ... 7.com
用户可以通过hash结构的url看到不同的内容。
http://www.51sjk.com/Upload/Ar ... m%231 http://www.51sjk.com/Upload/Ar ... m%232 http://www.51sjk.com/Upload/Ar ... m%233
但是,搜索引擎只会抓取并忽略井号,因此它们无法索引内容。
为了解决这个问题,谷歌提出了“井号+感叹号”的结构。
http://www.51sjk.com/Upload/Ar ... 3%211
当谷歌找到上述网址时,它会自动抓取另一个网址:
http://www.51sjk.com/Upload/Ar ... _%3D1
只要把ajax内容放到这个网址,google就会收录。但问题是“哈希+感叹号”非常丑陋和繁琐。Twitter曾经使用这种结构,它把
http://www.51sjk.com/Upload/Ar ... 9.jpg
改成
http://www.51sjk.com/Upload/Ar ... 4.jpg
结果,用户抱怨连连,只用了半年时间就废了。
那么,有没有什么办法可以让搜索引擎在保持更直观的URL的同时抓取ajax内容呢?
一直觉得没有办法,直到两天前看到话语创始人之一罗宾·沃德的解决方案,我才忍不住尖叫起来。
Discourse是一个严重依赖ajax的论坛程序,但它必须让google收录内容。它的解决方案是放弃hash结构,采用history api。
所谓history api,是指在不刷新页面的情况下,改变浏览器地址栏中显示的url(准确的说,就是改变网页的当前状态)。这是一个示例,您单击上面的按钮开始播放音乐。然后,点击下面的链接看看发生了什么?
地址栏的url变了,但音乐播放不中断!
history api的详细介绍超出了本文章的范围。简单来说,它的作用就是给浏览器的history对象添加一条记录。
window.history.pushstate(state object, title, url);
上面这行命令可以让地址栏中出现一个新的 URL。history对象的pushstate方法接受三个参数,new url为第三个参数,前两个参数可以为null。
window.history.pushstate(null, null, newurl);
目前主流浏览器都支持这种方式:chrome(26.0+)、firefox(20.0+)、ie(10.0+)、safari(5.1+),歌剧(12.1+)。
下面是robin ward的方法。
首先,将hash结构替换成history api,让每个hash符号变成一个正常路径的url,这样搜索引擎就会抓取每一个网页。
example.com/1 example.com/2 example.com/3
然后,定义一个javascript函数来处理ajax部分并根据URL抓取内容(假设使用jquery)。
function anchorclick(link) {
var linksplit = link.split('/').pop();
$.get('api/' + linksplit, function(data) {
$('#content').html(data);
});
}
然后定义鼠标的点击事件。
$('#container').on('click', 'a', function(e) {
window.history.pushstate(null, null, $(this).attr('href'));
anchorclick($(this).attr('href'));
e.preventdefault();
});
还要考虑用户点击浏览器的“前进/后退”按钮。这时候会触发history对象的popstate事件。
window.addeventlistener('popstate', function(e) {
anchorclick(location.pathname);
});
定义以上三段代码后,无需刷新页面即可显示正常路径url和ajax内容。
最后,设置服务器端。
因为没有使用 hashtag 结构,所以每个 URL 都是不同的请求。因此,服务器需要向所有这些请求返回具有以下结构的网页,以防止 404 错误。
... ...
如果你仔细看上面的代码,你会发现里面有一个 noscript 标签。这就是秘密。
我们将所有我们想要搜索引擎的内容放在了 noscript 标签中。在这种情况下,用户仍然可以在不刷新页面的情况下进行ajax操作,但是搜索引擎会收录每个页面的主要内容! 查看全部
ajax抓取网页内容(越来越+感叹号的解决方法放弃井号结构的url结构)
越来越多的网站开始采用“单页应用”。
整个网站只有一个网页,使用ajax技术根据用户的输入加载不同的内容。

这种方式的优点是用户体验好,节省流量。缺点是ajax内容无法被搜索引擎抓取。例如,您有一个 网站。
http://www.51sjk.com/Upload/Ar ... 7.com
用户可以通过hash结构的url看到不同的内容。
http://www.51sjk.com/Upload/Ar ... m%231 http://www.51sjk.com/Upload/Ar ... m%232 http://www.51sjk.com/Upload/Ar ... m%233
但是,搜索引擎只会抓取并忽略井号,因此它们无法索引内容。
为了解决这个问题,谷歌提出了“井号+感叹号”的结构。
http://www.51sjk.com/Upload/Ar ... 3%211
当谷歌找到上述网址时,它会自动抓取另一个网址:
http://www.51sjk.com/Upload/Ar ... _%3D1
只要把ajax内容放到这个网址,google就会收录。但问题是“哈希+感叹号”非常丑陋和繁琐。Twitter曾经使用这种结构,它把
http://www.51sjk.com/Upload/Ar ... 9.jpg
改成
http://www.51sjk.com/Upload/Ar ... 4.jpg
结果,用户抱怨连连,只用了半年时间就废了。
那么,有没有什么办法可以让搜索引擎在保持更直观的URL的同时抓取ajax内容呢?
一直觉得没有办法,直到两天前看到话语创始人之一罗宾·沃德的解决方案,我才忍不住尖叫起来。

Discourse是一个严重依赖ajax的论坛程序,但它必须让google收录内容。它的解决方案是放弃hash结构,采用history api。
所谓history api,是指在不刷新页面的情况下,改变浏览器地址栏中显示的url(准确的说,就是改变网页的当前状态)。这是一个示例,您单击上面的按钮开始播放音乐。然后,点击下面的链接看看发生了什么?

地址栏的url变了,但音乐播放不中断!
history api的详细介绍超出了本文章的范围。简单来说,它的作用就是给浏览器的history对象添加一条记录。
window.history.pushstate(state object, title, url);
上面这行命令可以让地址栏中出现一个新的 URL。history对象的pushstate方法接受三个参数,new url为第三个参数,前两个参数可以为null。
window.history.pushstate(null, null, newurl);
目前主流浏览器都支持这种方式:chrome(26.0+)、firefox(20.0+)、ie(10.0+)、safari(5.1+),歌剧(12.1+)。
下面是robin ward的方法。
首先,将hash结构替换成history api,让每个hash符号变成一个正常路径的url,这样搜索引擎就会抓取每一个网页。
example.com/1 example.com/2 example.com/3
然后,定义一个javascript函数来处理ajax部分并根据URL抓取内容(假设使用jquery)。
function anchorclick(link) {
var linksplit = link.split('/').pop();
$.get('api/' + linksplit, function(data) {
$('#content').html(data);
});
}
然后定义鼠标的点击事件。
$('#container').on('click', 'a', function(e) {
window.history.pushstate(null, null, $(this).attr('href'));
anchorclick($(this).attr('href'));
e.preventdefault();
});
还要考虑用户点击浏览器的“前进/后退”按钮。这时候会触发history对象的popstate事件。
window.addeventlistener('popstate', function(e) {
anchorclick(location.pathname);
});
定义以上三段代码后,无需刷新页面即可显示正常路径url和ajax内容。
最后,设置服务器端。
因为没有使用 hashtag 结构,所以每个 URL 都是不同的请求。因此,服务器需要向所有这些请求返回具有以下结构的网页,以防止 404 错误。
... ...
如果你仔细看上面的代码,你会发现里面有一个 noscript 标签。这就是秘密。
我们将所有我们想要搜索引擎的内容放在了 noscript 标签中。在这种情况下,用户仍然可以在不刷新页面的情况下进行ajax操作,但是搜索引擎会收录每个页面的主要内容!
ajax抓取网页内容(越来越多的网站采用“单页应用”的解决办法)
网站优化 • 优采云 发表了文章 • 0 个评论 • 47 次浏览 • 2021-12-21 01:08
越来越多的网站开始采用“单页应用”。
整个网站只有一个网页,它使用Ajax技术根据用户输入加载不同的内容。
这种方式的优点是用户体验好,节省流量。缺点是搜索引擎无法抓取 AJAX 内容。例如,您有一个 网站。
用户可以通过具有哈希结构的 URL 看到不同的内容。
# 1 # 2 # 3 但是,搜索引擎只会抓取,忽略哈希符号,因此无法索引内容。
为了解决这个问题,谷歌提出了“感叹号”的结构。
#!1 当谷歌发现这样一个网址时,它会自动抓取另一个网址:
只要你把AJAX内容放到这个网站上,Google就会收录。但问题是'感叹号'非常丑陋和笨重。Twitter 过去使用这种结构,它把
变成
#!/Ruan Yifei 结果,用户抱怨连连,只用了半年时间就废了。
那么,有没有什么方法可以让搜索引擎在抓取 AJAX 内容的同时保持直观的 URL 呢?
一直觉得做不到,直到前两天看到《话语》创始人之一罗宾·沃德的解决方案,我才忍不住尖叫起来。
Discourse 是一个严重依赖 Ajax 的论坛程序,但 Google 必须收录内容。解决方案是放弃hashtag结构,采用历史API。
所谓history API,就是在不刷新页面的情况下,改变浏览器地址栏中显示的URL(准确的说,就是改变网页的当前状态)。这是一个例子。您单击上面的按钮开始播放音乐。然后,单击下面的链接,看看发生了什么。
地址栏中的网址已更改,但音乐播放并未中断!
对历史 API 的详细介绍超出了本文的范围。简单的说,它的作用就是给浏览器的History对象添加一条记录。
window.history.pushState(状态对象、标题、URL);上面的命令可以在地址栏中显示一个新的 URL。History对象的pushState方法接受三个参数,新的URL为第三个参数,前两个参数可以为空。
window.history.pushState(null, null, new URl); 目前主流浏览器都支持这种方式:Chrome(26.0), Firefox(20.0), IE(10.0), Safari(5.1), Opera(12.1).
以下是Robin Ward 的方法。
首先用History API替换hash结构,让每一个hash都变成一个正常路径的URL,这样搜索引擎就会抓取每一个网页。
然后, ///3 定义一个 JavaScript 函数来处理 Ajax 并根据 URL 抓取内容(假设使用了 jQuery)。
函数 anchorClick(link){ var linkSplit=link. 分裂('/')。流行音乐(); $.get('api/' linkSplit, function (data){$('#content').html(data);});} 然后定义鼠标点击事件。
$('#container')。on('click',' a',function(e){ window.history.push state(null,null,$(this)).attr(' href'); anchorClick($(this).attr(' href '); e.PreventDefault();}); 还要考虑用户点击了浏览器的“前进/后退”按钮,此时触发了历史对象的popstate事件。
窗户。addeventlistener('pop state', function (e){ anchorClick(location .pathname);}); 定义以上三个代码后,无需刷新页面即可显示正常路径URL和AJAX内容。
最后,设置服务器端。
因为没有使用哈希结构,所以每个 URL 都是不同的请求。因此,服务器需要为所有这些请求返回一个具有以下结构的网页,以防止 404 错误。
htmlbody section id='container'/section noscript./noscript/body/html 仔细看上面的代码,你会发现里面有一个no script标签,这就是秘诀。
我们将搜索引擎中收录的所有内容都放在 noscript 标签中。这样,用户仍然可以在不刷新页面的情况下进行AJAX操作,但是搜索引擎会记录每个页面的主要内容! 查看全部
ajax抓取网页内容(越来越多的网站采用“单页应用”的解决办法)
越来越多的网站开始采用“单页应用”。
整个网站只有一个网页,它使用Ajax技术根据用户输入加载不同的内容。

这种方式的优点是用户体验好,节省流量。缺点是搜索引擎无法抓取 AJAX 内容。例如,您有一个 网站。
用户可以通过具有哈希结构的 URL 看到不同的内容。
# 1 # 2 # 3 但是,搜索引擎只会抓取,忽略哈希符号,因此无法索引内容。
为了解决这个问题,谷歌提出了“感叹号”的结构。
#!1 当谷歌发现这样一个网址时,它会自动抓取另一个网址:
只要你把AJAX内容放到这个网站上,Google就会收录。但问题是'感叹号'非常丑陋和笨重。Twitter 过去使用这种结构,它把
变成
#!/Ruan Yifei 结果,用户抱怨连连,只用了半年时间就废了。
那么,有没有什么方法可以让搜索引擎在抓取 AJAX 内容的同时保持直观的 URL 呢?
一直觉得做不到,直到前两天看到《话语》创始人之一罗宾·沃德的解决方案,我才忍不住尖叫起来。

Discourse 是一个严重依赖 Ajax 的论坛程序,但 Google 必须收录内容。解决方案是放弃hashtag结构,采用历史API。
所谓history API,就是在不刷新页面的情况下,改变浏览器地址栏中显示的URL(准确的说,就是改变网页的当前状态)。这是一个例子。您单击上面的按钮开始播放音乐。然后,单击下面的链接,看看发生了什么。

地址栏中的网址已更改,但音乐播放并未中断!
对历史 API 的详细介绍超出了本文的范围。简单的说,它的作用就是给浏览器的History对象添加一条记录。
window.history.pushState(状态对象、标题、URL);上面的命令可以在地址栏中显示一个新的 URL。History对象的pushState方法接受三个参数,新的URL为第三个参数,前两个参数可以为空。
window.history.pushState(null, null, new URl); 目前主流浏览器都支持这种方式:Chrome(26.0), Firefox(20.0), IE(10.0), Safari(5.1), Opera(12.1).
以下是Robin Ward 的方法。
首先用History API替换hash结构,让每一个hash都变成一个正常路径的URL,这样搜索引擎就会抓取每一个网页。
然后, ///3 定义一个 JavaScript 函数来处理 Ajax 并根据 URL 抓取内容(假设使用了 jQuery)。
函数 anchorClick(link){ var linkSplit=link. 分裂('/')。流行音乐(); $.get('api/' linkSplit, function (data){$('#content').html(data);});} 然后定义鼠标点击事件。
$('#container')。on('click',' a',function(e){ window.history.push state(null,null,$(this)).attr(' href'); anchorClick($(this).attr(' href '); e.PreventDefault();}); 还要考虑用户点击了浏览器的“前进/后退”按钮,此时触发了历史对象的popstate事件。
窗户。addeventlistener('pop state', function (e){ anchorClick(location .pathname);}); 定义以上三个代码后,无需刷新页面即可显示正常路径URL和AJAX内容。
最后,设置服务器端。
因为没有使用哈希结构,所以每个 URL 都是不同的请求。因此,服务器需要为所有这些请求返回一个具有以下结构的网页,以防止 404 错误。
htmlbody section id='container'/section noscript./noscript/body/html 仔细看上面的代码,你会发现里面有一个no script标签,这就是秘诀。
我们将搜索引擎中收录的所有内容都放在 noscript 标签中。这样,用户仍然可以在不刷新页面的情况下进行AJAX操作,但是搜索引擎会记录每个页面的主要内容!
ajax抓取网页内容(抓ajax异步内容页面和抓普通的页面区别。 )
网站优化 • 优采云 发表了文章 • 0 个评论 • 54 次浏览 • 2021-12-20 04:14
)
其实抓取ajax异步内容页面和抓取普通页面没有太大区别。 Ajax 只是发出一个异步 http 请求。用类似firebug的工具,找到请求的后端服务url和传参值,然后抓取url传参即可。
使用 Firebug 的网络工具
如果抓取一个页面,内容中没有显示的数据是一堆JS代码。
代码
$cookie_file=tempnam('./temp','cookie');
$ch = curl_init();
$url1 = "http://www.cdut.edu.cn/default.html";
curl_setopt($ch,CURLOPT_URL,$url1);
curl_setopt($ch,CURLOPT_HTTP_VERSION,CURL_HTTP_VERSION_1_1);
curl_setopt($ch,CURLOPT_HEADER,0);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch,CURLOPT_FOLLOWLOCATION,1);
curl_setopt($ch, CURLOPT_ENCODING ,'gzip'); //加入gzip解析
//设置连接结束后保存cookie信息的文件
curl_setopt($ch,CURLOPT_COOKIEJAR,$cookie_file);
$content=curl_exec($ch);
curl_close($ch);
$ch3 = curl_init();
$url3 = "http://www.cdut.edu.cn/xww/dwr ... 3B%3B
$curlPost = "callCount=1&page=/xww/type/1000020118.html&httpSessionId=12A9B726E6A2D4D3B09DE7952B2F282C&scriptSessionId=295315B4B4141B09DA888D3A3ADB8FAA658&c0-scriptName=portalAjax&c0-methodName=getNewsXml&c0-id=0&c0-param0=string:10000201&c0-param1=string:1000020118&c0-param2=string:news_&c0-param3=number:5969&c0-param4=number:1&c0-param5=null:null&c0-param6=null:null&batchId=0";
curl_setopt($ch3,CURLOPT_URL,$url3);
curl_setopt($ch3,CURLOPT_POST,1);
curl_setopt($ch3,CURLOPT_POSTFIELDS,$curlPost);
//设置连接结束后保存cookie信息的文件
curl_setopt($ch3,CURLOPT_COOKIEFILE,$cookie_file);
$content1=curl_exec($ch3);
curl_close($ch3); 查看全部
ajax抓取网页内容(抓ajax异步内容页面和抓普通的页面区别。
)
其实抓取ajax异步内容页面和抓取普通页面没有太大区别。 Ajax 只是发出一个异步 http 请求。用类似firebug的工具,找到请求的后端服务url和传参值,然后抓取url传参即可。
使用 Firebug 的网络工具

如果抓取一个页面,内容中没有显示的数据是一堆JS代码。

代码
$cookie_file=tempnam('./temp','cookie');
$ch = curl_init();
$url1 = "http://www.cdut.edu.cn/default.html";
curl_setopt($ch,CURLOPT_URL,$url1);
curl_setopt($ch,CURLOPT_HTTP_VERSION,CURL_HTTP_VERSION_1_1);
curl_setopt($ch,CURLOPT_HEADER,0);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch,CURLOPT_FOLLOWLOCATION,1);
curl_setopt($ch, CURLOPT_ENCODING ,'gzip'); //加入gzip解析
//设置连接结束后保存cookie信息的文件
curl_setopt($ch,CURLOPT_COOKIEJAR,$cookie_file);
$content=curl_exec($ch);
curl_close($ch);
$ch3 = curl_init();
$url3 = "http://www.cdut.edu.cn/xww/dwr ... 3B%3B
$curlPost = "callCount=1&page=/xww/type/1000020118.html&httpSessionId=12A9B726E6A2D4D3B09DE7952B2F282C&scriptSessionId=295315B4B4141B09DA888D3A3ADB8FAA658&c0-scriptName=portalAjax&c0-methodName=getNewsXml&c0-id=0&c0-param0=string:10000201&c0-param1=string:1000020118&c0-param2=string:news_&c0-param3=number:5969&c0-param4=number:1&c0-param5=null:null&c0-param6=null:null&batchId=0";
curl_setopt($ch3,CURLOPT_URL,$url3);
curl_setopt($ch3,CURLOPT_POST,1);
curl_setopt($ch3,CURLOPT_POSTFIELDS,$curlPost);
//设置连接结束后保存cookie信息的文件
curl_setopt($ch3,CURLOPT_COOKIEFILE,$cookie_file);
$content1=curl_exec($ch3);
curl_close($ch3);
ajax抓取网页内容(百度网络蜘蛛更有效识别页面文字内容并建议涉及开发网页)
网站优化 • 优采云 发表了文章 • 0 个评论 • 60 次浏览 • 2021-12-18 16:07
A 网站只有百度把尽可能多的页面收录进入索引库,才能获得更好的权重,进而促进网站获得更好的曝光率,所以百度网络蜘蛛可以有效地捕捉 抓取页面是关键词排名的第一步,其他搜索引擎一般也是这样做的。百度的收录网站页面的机制是通过一个叫Baiduspider的蜘蛛程序自动抓取互联网上的网页,处理后存入索引库。目前百度蜘蛛只能读取文本内容。Flash、图片、视频、JavaScript等非文本内容暂时无法处理。因此,很多公司网站为了美观的界面,把文字和图片放在flash里,百度却认不出来。
1、 尽量使用有效的文字代替flash、图片、Javascript等来展示网页中的重要内容或链接。如果为了页面美观需要使用图片,建议图片必须设置有效的关键词 Alt属性,图片周围必须有可以描述图片的文字,最好有关键字。
2、 随着网络技术和带宽的进步,有时需要在网页中安排动画、视频、音频等多媒体元素,以更好地说明产品说明、公司的生产实力、公司的技术水平,获得了网友的高度信任。,为了更好的服务模板客户,网站将使用音频、视频等多媒体元素。建议在网页的这部分尽可能同时提供文字说明。文字说明可以使用必要的技术,不要在网页上显示。
3、 Ajax 和其他搜索引擎无法识别的技术只在需要用户交互的地方使用,而您希望搜索引擎“看到”的导航和文本内容不会放入 Ajax。尽量少用frame和iframe结构,通过iframe显示的内容可能会被百度丢弃。 查看全部
ajax抓取网页内容(百度网络蜘蛛更有效识别页面文字内容并建议涉及开发网页)
A 网站只有百度把尽可能多的页面收录进入索引库,才能获得更好的权重,进而促进网站获得更好的曝光率,所以百度网络蜘蛛可以有效地捕捉 抓取页面是关键词排名的第一步,其他搜索引擎一般也是这样做的。百度的收录网站页面的机制是通过一个叫Baiduspider的蜘蛛程序自动抓取互联网上的网页,处理后存入索引库。目前百度蜘蛛只能读取文本内容。Flash、图片、视频、JavaScript等非文本内容暂时无法处理。因此,很多公司网站为了美观的界面,把文字和图片放在flash里,百度却认不出来。
1、 尽量使用有效的文字代替flash、图片、Javascript等来展示网页中的重要内容或链接。如果为了页面美观需要使用图片,建议图片必须设置有效的关键词 Alt属性,图片周围必须有可以描述图片的文字,最好有关键字。
2、 随着网络技术和带宽的进步,有时需要在网页中安排动画、视频、音频等多媒体元素,以更好地说明产品说明、公司的生产实力、公司的技术水平,获得了网友的高度信任。,为了更好的服务模板客户,网站将使用音频、视频等多媒体元素。建议在网页的这部分尽可能同时提供文字说明。文字说明可以使用必要的技术,不要在网页上显示。
3、 Ajax 和其他搜索引擎无法识别的技术只在需要用户交互的地方使用,而您希望搜索引擎“看到”的导航和文本内容不会放入 Ajax。尽量少用frame和iframe结构,通过iframe显示的内容可能会被百度丢弃。
ajax抓取网页内容(ajax都搜不到我们的页面你以为你尽力了吗)
网站优化 • 优采云 发表了文章 • 0 个评论 • 38 次浏览 • 2021-12-18 04:04
说到Ajax的缺点,很多人会认为不利于SEO的一面。大搜索时代,搜索引擎找不到我们的页面,你肯定会有淡淡的忧伤。你认为你尽力了,显然没有,那我们该怎么办?
一、先回顾一下ajax的一些不足,
①破坏浏览器的后退按钮,使其无法运行;
②对搜索引擎不友好;
③不支持跨域请求;
④ ajax脚本语言嵌入在HTML页面中,可以通过查看源代码或firebug等工具直接查看,不利于项目代码的保密。
第二个提到了,对搜索引擎不友好。这意味着什么?这么说吧,越来越多的网站开始采用“单页结构”。整个网站只有一个网页,使用ajax技术根据用户输入加载不同的内容。
这种方式的优点是用户体验好,节省流量。缺点是ajax内容无法被搜索引擎抓取。因为搜索引擎会爬取整个页面的内容,这样统计数据才能达到搜索的目的,而且Ajax请求的文件在用户操作之前放在服务器上,无论搜索引擎有多强大,信息或无法搜索资源。.
因此,缺点是显而易见的。之前也想过这个问题,但是没有很好的解决办法。直到看到这个文章,忍不住拍案叫绝,分享出来供大家参考:
how_to_make_search_engines_find_ajax_content
二、如何解决
1. 将hashtag结构替换为History API,让每个hashtag变成正常路径的URL,这样搜索引擎就会抓取每一个网页。
1<br />2<br />3<br />
example.com/1<br />example.com/2<br />example.com/3<br />
2.定义一个 JavaScript 函数来处理 Ajax 部分并根据 URL 抓取内容(假设使用 jQuery)。
1<br />2<br />3<br />4<br />5<br />6<br />
function anchorClick(link) {<br /> var linkSplit = link.split('/').pop();<br /> $.get('api/' + linkSplit, function(data) {<br /> $('#content').html(data);<br /> });<br />}<br />
然后定义鼠标的点击事件。
1<br />2<br />3<br />4<br />5<br />
$('#container').on('click', 'a', function(e) {<br /> window.history.pushState(null, null, $(this).attr('href'));<br /> anchorClick($(this).attr('href'));<br /> e.preventDefault();<br />});<br />
还要考虑用户单击浏览器的“前进/后退”按钮。这时候会触发History对象的popstate事件。
1<br />2<br />3<br />
window.addEventListener('popstate', function(e) {<br /> anchorClick(location.pathname);<br />});<br />
定义以上三段代码后,无需刷新页面即可显示正常路径URL和AJAX内容。
3.设置服务器端。
因为没有使用 hashtag 结构,所以每个 URL 都是不同的请求。因此,服务器需要向所有这些请求返回具有以下结构的网页,以防止 404 错误。
1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />
<br /> <br /> <br /> <br /> ... ...<br /> <br /> <br /><br />
总之,意思很明确。就是用js把url拼出来写进地址栏,这样搜索引擎当然可以抓取页面的内容。 查看全部
ajax抓取网页内容(ajax都搜不到我们的页面你以为你尽力了吗)
说到Ajax的缺点,很多人会认为不利于SEO的一面。大搜索时代,搜索引擎找不到我们的页面,你肯定会有淡淡的忧伤。你认为你尽力了,显然没有,那我们该怎么办?
一、先回顾一下ajax的一些不足,
①破坏浏览器的后退按钮,使其无法运行;
②对搜索引擎不友好;
③不支持跨域请求;
④ ajax脚本语言嵌入在HTML页面中,可以通过查看源代码或firebug等工具直接查看,不利于项目代码的保密。
第二个提到了,对搜索引擎不友好。这意味着什么?这么说吧,越来越多的网站开始采用“单页结构”。整个网站只有一个网页,使用ajax技术根据用户输入加载不同的内容。
这种方式的优点是用户体验好,节省流量。缺点是ajax内容无法被搜索引擎抓取。因为搜索引擎会爬取整个页面的内容,这样统计数据才能达到搜索的目的,而且Ajax请求的文件在用户操作之前放在服务器上,无论搜索引擎有多强大,信息或无法搜索资源。.
因此,缺点是显而易见的。之前也想过这个问题,但是没有很好的解决办法。直到看到这个文章,忍不住拍案叫绝,分享出来供大家参考:
how_to_make_search_engines_find_ajax_content
二、如何解决
1. 将hashtag结构替换为History API,让每个hashtag变成正常路径的URL,这样搜索引擎就会抓取每一个网页。
1<br />2<br />3<br />
example.com/1<br />example.com/2<br />example.com/3<br />
2.定义一个 JavaScript 函数来处理 Ajax 部分并根据 URL 抓取内容(假设使用 jQuery)。
1<br />2<br />3<br />4<br />5<br />6<br />
function anchorClick(link) {<br /> var linkSplit = link.split('/').pop();<br /> $.get('api/' + linkSplit, function(data) {<br /> $('#content').html(data);<br /> });<br />}<br />
然后定义鼠标的点击事件。
1<br />2<br />3<br />4<br />5<br />
$('#container').on('click', 'a', function(e) {<br /> window.history.pushState(null, null, $(this).attr('href'));<br /> anchorClick($(this).attr('href'));<br /> e.preventDefault();<br />});<br />
还要考虑用户单击浏览器的“前进/后退”按钮。这时候会触发History对象的popstate事件。
1<br />2<br />3<br />
window.addEventListener('popstate', function(e) {<br /> anchorClick(location.pathname);<br />});<br />
定义以上三段代码后,无需刷新页面即可显示正常路径URL和AJAX内容。
3.设置服务器端。
因为没有使用 hashtag 结构,所以每个 URL 都是不同的请求。因此,服务器需要向所有这些请求返回具有以下结构的网页,以防止 404 错误。
1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />
<br /> <br /> <br /> <br /> ... ...<br /> <br /> <br /><br />
总之,意思很明确。就是用js把url拼出来写进地址栏,这样搜索引擎当然可以抓取页面的内容。
ajax抓取网页内容(常见的反爬机制及处理方式-苏州安嘉网络)
网站优化 • 优采云 发表了文章 • 0 个评论 • 35 次浏览 • 2021-12-14 19:24
常见的防爬机构及处理方法
1、Headers 反爬虫:Cookie、Referer、User-Agent
解决方法:通过F12获取headers,传递给requests.get()方法
2、IP限制:网站根据IP地址访问频率反爬,短时间内IP访问
解决方案:
1、 构建自己的IP代理池,每次访问随机选择代理,频繁更新代理池
2、购买开放代理或私有代理IP
3、降低爬行速度
3、User-Agent 限制:类似于 IP 限制
解决方案:构建自己的User-Agent池,每次访问随机选择
5、查询参数或表单数据的认证(salt,sign)
解决方法:找到JS文件,分析JS处理方式,用Python同样处理
6、处理响应内容
解决方法:打印查看响应内容,使用xpath或者正则处理
python中标题和表单数据的常规处理
1、pycharm 进入方法:Ctrl + r,选择Regex
2、处理标头和表单数据
(.*): (.*)
"1":"1":"2",
3、点击全部替换
民政部网站数据采集
目标:抓取中华人民共和国县级以上最新行政区划代码
网址:-民政数据-行政部门代码
实施步骤
1、民政数据提取最新行政区划代码链接网站
最新在上,命名格式:X,2019,中华人民共和国县及以上行政区划代码
import requests
from lxml import etree
import re
url = 'http://www.mca.gov.cn/article/sj/xzqh/2019/'
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36'}
html = requests.get(url, headers=headers).text
parse_html = etree.HTML(html)
article_list = parse_html.xpath('//a[@class="artitlelist"]')
for article in article_list:
title = article.xpath('./@title')[0]
# 正则匹配title中包含这个字符串的链接
if title.endswith('代码'):
# 获取到第1个就停止即可,第1个永远是最新的链接
two_link = 'http://www.mca.gov.cn' + article.xpath('./@href')[0]
print(two_link)
break
2、 从二级页面链接中提取真实链接(反爬-响应在网页内容中嵌入JS,指向新的网页链接)
向二级页面链接发送请求获取响应内容,查看嵌入的JS代码
定期提取真实二级页面链接
# 爬取二级“假”链接
two_html = requests.get(two_link, headers=headers).text
# 从二级页面的响应中提取真实的链接(此处为JS动态加载跳转的地址)
new_two_link = re.findall(r'window.location.href="(.*?)" rel="external nofollow" rel="external nofollow" ', two_html, re.S)[0]
3、在数据库表中查询该链接是否被爬取过,构建增量爬虫
在数据库中创建一个版本表来存储爬取的链接
每次执行程序都会记录版本表,查看是否被爬取过
cursor.execute('select * from version')
result = self.cursor.fetchall()
if result:
if result[-1][0] == two_link:
print('已是最新')
else:
# 有更新,开始抓取
# 将链接再重新插入version表记录
4、代码实现
import requests
from lxml import etree
import re
import pymysql
class GovementSpider(object):
def __init__(self):
self.url = 'http://www.mca.gov.cn/article/sj/xzqh/2019/'
self.headers = {'User-Agent': 'Mozilla/5.0'}
# 创建2个对象
self.db = pymysql.connect('127.0.0.1', 'root', '123456', 'govdb', charset='utf8')
self.cursor = self.db.cursor()
# 获取假链接
def get_false_link(self):
html = requests.get(url=self.url, headers=self.headers).text
# 此处隐藏了真实的二级页面的url链接,真实的在假的响应网页中,通过js脚本生成,
# 假的链接在网页中可以访问,但是爬取到的内容却不是我们想要的
parse_html = etree.HTML(html)
a_list = parse_html.xpath('//a[@class="artitlelist"]')
for a in a_list:
# get()方法:获取某个属性的值
title = a.get('title')
if title.endswith('代码'):
# 获取到第1个就停止即可,第1个永远是最新的链接
false_link = 'http://www.mca.gov.cn' + a.get('href')
print("二级“假”链接的网址为", false_link)
break
# 提取真链接
self.incr_spider(false_link)
# 增量爬取函数
def incr_spider(self, false_link):
self.cursor.execute('select url from version where url=%s', [false_link])
# fetchall: (('http://xxxx.html',),)
result = self.cursor.fetchall()
# not result:代表数据库version表中无数据
if not result:
self.get_true_link(false_link)
# 可选操作: 数据库version表中只保留最新1条数据
self.cursor.execute("delete from version")
# 把爬取后的url插入到version表中
self.cursor.execute('insert into version values(%s)', [false_link])
self.db.commit()
else:
print('数据已是最新,无须爬取')
# 获取真链接
def get_true_link(self, false_link):
# 先获取假链接的响应,然后根据响应获取真链接
html = requests.get(url=false_link, headers=self.headers).text
# 从二级页面的响应中提取真实的链接(此处为JS动态加载跳转的地址)
re_bds = r'window.location.href="(.*?)" rel="external nofollow" rel="external nofollow" '
pattern = re.compile(re_bds, re.S)
true_link = pattern.findall(html)[0]
self.save_data(true_link) # 提取真链接的数据
# 用xpath直接提取数据
def save_data(self, true_link):
html = requests.get(url=true_link, headers=self.headers).text
# 基准xpath,提取每个信息的节点列表对象
parse_html = etree.HTML(html)
tr_list = parse_html.xpath('//tr[@height="19"]')
for tr in tr_list:
code = tr.xpath('./td[2]/text()')[0].strip() # 行政区划代码
name = tr.xpath('./td[3]/text()')[0].strip() # 单位名称
print(name, code)
# 主函数
def main(self):
self.get_false_link()
if __name__ == '__main__':
spider = GovementSpider()
spider.main()
动态加载数据捕获-Ajax
特征
右键->查看没有具体数据的网页源代码
滚动鼠标滚轮或其他动作时加载
抓
F12打开控制台,选择XHR异步加载数据包,找到page action抓取网络数据包
通过XHR-->Header-->General-->Request URL获取json文件的URL地址
通过XHR-->Header-->查询字符串参数
豆瓣电影数据采集案例
目标
地址:豆瓣电影排行榜-故事
type_name=%E5%89%A7%E6%83%85&type=11&interval_id=100:90&action=
目标:抓取电影名称、电影评级
F12 数据包捕获 (XHR)
1、请求 URL(基本 URL 地址):
2、Query String Paramaters(查询参数)
# 查询参数如下:
type: 13 # 电影类型
interval_id: 100:90
action: '[{},{},{}]'
start: 0 # 每次加载电影的起始索引值
limit: 20 # 每次加载的电影数量
json文件位于以下地址:
基本 URL 地址 + 查询参数
''+'type=11&interval_id=100%3A90&action=&start=20&limit=20'
代码
import requests
import time
from fake_useragent import UserAgent
class DoubanSpider(object):
def __init__(self):
self.base_url = 'https://movie.douban.com/j/chart/top_list?'
self.i = 0
def get_html(self, params):
headers = {'User-Agent': UserAgent().random}
res = requests.get(url=self.base_url, params=params, headers=headers)
res.encoding = 'utf-8'
html = res.json() # 将json格式的字符串转为python数据类型
self.parse_html(html) # 直接调用解析函数
def parse_html(self, html):
# html: [{电影1信息},{电影2信息},{}]
item = {}
for one in html:
item['name'] = one['title'] # 电影名
item['score'] = one['score'] # 评分
item['time'] = one['release_date'] # 打印测试
# 打印显示
print(item)
self.i += 1
# 获取电影总数
def get_total(self, typ):
# 异步动态加载的数据 都可以在XHR数据抓包
url = 'https://movie.douban.com/j/chart/top_list_count?type={}&interval_id=100%3A90'.format(typ)
ua = UserAgent()
html = requests.get(url=url, headers={'User-Agent': ua.random}).json()
total = html['total']
return total
def main(self):
typ = input('请输入电影类型(剧情|喜剧|动作):')
typ_dict = {'剧情': '11', '喜剧': '24', '动作': '5'}
typ = typ_dict[typ]
total = self.get_total(typ) # 获取该类型电影总数量
for page in range(0, int(total), 20):
params = {
'type': typ,
'interval_id': '100:90',
'action': '',
'start': str(page),
'limit': '20'}
self.get_html(params)
time.sleep(1)
print('爬取的电影的数量:', self.i)
if __name__ == '__main__':
spider = DoubanSpider()
spider.main()
腾讯招聘数据抓取(Ajax)
确定 URL 地址和目标
网址:百度搜索腾讯招聘-查看职位
目标:职位名称、工作职责、工作要求
需求与分析
通过查看网页源代码,我们知道所有需要的数据都是Ajax动态加载的
通过F12捕获网络数据包进行分析
一级页面爬取数据:职位
在二级页面上抓取数据:工作职责、工作要求
一级页面的json地址(pageIndex在变化,时间戳不检查)
{}&pageSize=10&language=zh-cn&area=cn
二级页面地址(postId在变化,可以在一级页面获取)
{}&language=zh-cn
用户代理.py文件
ua_list = [
'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.163 Safari/535.1',
'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0) Gecko/20100101 Firefox/6.0',
'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; InfoPath.3)',
]
import time
import json
import random
import requests
from useragents import ua_list
class TencentSpider(object):
def __init__(self):
self.one_url = 'https://careers.tencent.com/tencentcareer/api/post/Query?timestamp=1563912271089&countryId=&cityId=&bgIds=&productId=&categoryId=&parentCategoryId=&attrId=&keyword=&pageIndex={}&pageSize=10&language=zh-cn&area=cn'
self.two_url = 'https://careers.tencent.com/tencentcareer/api/post/ByPostId?timestamp=1563912374645&postId={}&language=zh-cn'
self.f = open('tencent.json', 'a') # 打开文件
self.item_list = [] # 存放抓取的item字典数据
# 获取响应内容函数
def get_page(self, url):
headers = {'User-Agent': random.choice(ua_list)}
html = requests.get(url=url, headers=headers).text
html = json.loads(html) # json格式字符串转为Python数据类型
return html
# 主线函数: 获取所有数据
def parse_page(self, one_url):
html = self.get_page(one_url)
item = {}
for job in html['Data']['Posts']:
item['name'] = job['RecruitPostName'] # 名称
post_id = job['PostId'] # postId,拿postid为了拼接二级页面地址
# 拼接二级地址,获取职责和要求
two_url = self.two_url.format(post_id)
item['duty'], item['require'] = self.parse_two_page(two_url)
print(item)
self.item_list.append(item) # 添加到大列表中
# 解析二级页面函数
def parse_two_page(self, two_url):
html = self.get_page(two_url)
duty = html['Data']['Responsibility'] # 工作责任
duty = duty.replace('\r\n', '').replace('\n', '') # 去掉换行
require = html['Data']['Requirement'] # 工作要求
require = require.replace('\r\n', '').replace('\n', '') # 去掉换行
return duty, require
# 获取总页数
def get_numbers(self):
url = self.one_url.format(1)
html = self.get_page(url)
numbers = int(html['Data']['Count']) // 10 + 1 # 每页有10个推荐
return numbers
def main(self):
number = self.get_numbers()
for page in range(1, 3):
one_url = self.one_url.format(page)
self.parse_page(one_url)
# 保存到本地json文件:json.dump
json.dump(self.item_list, self.f, ensure_ascii=False)
self.f.close()
if __name__ == '__main__':
start = time.time()
spider = TencentSpider()
spider.main()
end = time.time()
print('执行时间:%.2f' % (end - start))
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持面圈教程。 查看全部
ajax抓取网页内容(常见的反爬机制及处理方式-苏州安嘉网络)
常见的防爬机构及处理方法
1、Headers 反爬虫:Cookie、Referer、User-Agent
解决方法:通过F12获取headers,传递给requests.get()方法
2、IP限制:网站根据IP地址访问频率反爬,短时间内IP访问
解决方案:
1、 构建自己的IP代理池,每次访问随机选择代理,频繁更新代理池
2、购买开放代理或私有代理IP
3、降低爬行速度
3、User-Agent 限制:类似于 IP 限制
解决方案:构建自己的User-Agent池,每次访问随机选择
5、查询参数或表单数据的认证(salt,sign)
解决方法:找到JS文件,分析JS处理方式,用Python同样处理
6、处理响应内容
解决方法:打印查看响应内容,使用xpath或者正则处理
python中标题和表单数据的常规处理
1、pycharm 进入方法:Ctrl + r,选择Regex
2、处理标头和表单数据
(.*): (.*)
"1":"1":"2",
3、点击全部替换
民政部网站数据采集
目标:抓取中华人民共和国县级以上最新行政区划代码
网址:-民政数据-行政部门代码
实施步骤
1、民政数据提取最新行政区划代码链接网站
最新在上,命名格式:X,2019,中华人民共和国县及以上行政区划代码
import requests
from lxml import etree
import re
url = 'http://www.mca.gov.cn/article/sj/xzqh/2019/'
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36'}
html = requests.get(url, headers=headers).text
parse_html = etree.HTML(html)
article_list = parse_html.xpath('//a[@class="artitlelist"]')
for article in article_list:
title = article.xpath('./@title')[0]
# 正则匹配title中包含这个字符串的链接
if title.endswith('代码'):
# 获取到第1个就停止即可,第1个永远是最新的链接
two_link = 'http://www.mca.gov.cn' + article.xpath('./@href')[0]
print(two_link)
break
2、 从二级页面链接中提取真实链接(反爬-响应在网页内容中嵌入JS,指向新的网页链接)
向二级页面链接发送请求获取响应内容,查看嵌入的JS代码
定期提取真实二级页面链接
# 爬取二级“假”链接
two_html = requests.get(two_link, headers=headers).text
# 从二级页面的响应中提取真实的链接(此处为JS动态加载跳转的地址)
new_two_link = re.findall(r'window.location.href="(.*?)" rel="external nofollow" rel="external nofollow" ', two_html, re.S)[0]
3、在数据库表中查询该链接是否被爬取过,构建增量爬虫
在数据库中创建一个版本表来存储爬取的链接
每次执行程序都会记录版本表,查看是否被爬取过
cursor.execute('select * from version')
result = self.cursor.fetchall()
if result:
if result[-1][0] == two_link:
print('已是最新')
else:
# 有更新,开始抓取
# 将链接再重新插入version表记录
4、代码实现
import requests
from lxml import etree
import re
import pymysql
class GovementSpider(object):
def __init__(self):
self.url = 'http://www.mca.gov.cn/article/sj/xzqh/2019/'
self.headers = {'User-Agent': 'Mozilla/5.0'}
# 创建2个对象
self.db = pymysql.connect('127.0.0.1', 'root', '123456', 'govdb', charset='utf8')
self.cursor = self.db.cursor()
# 获取假链接
def get_false_link(self):
html = requests.get(url=self.url, headers=self.headers).text
# 此处隐藏了真实的二级页面的url链接,真实的在假的响应网页中,通过js脚本生成,
# 假的链接在网页中可以访问,但是爬取到的内容却不是我们想要的
parse_html = etree.HTML(html)
a_list = parse_html.xpath('//a[@class="artitlelist"]')
for a in a_list:
# get()方法:获取某个属性的值
title = a.get('title')
if title.endswith('代码'):
# 获取到第1个就停止即可,第1个永远是最新的链接
false_link = 'http://www.mca.gov.cn' + a.get('href')
print("二级“假”链接的网址为", false_link)
break
# 提取真链接
self.incr_spider(false_link)
# 增量爬取函数
def incr_spider(self, false_link):
self.cursor.execute('select url from version where url=%s', [false_link])
# fetchall: (('http://xxxx.html',),)
result = self.cursor.fetchall()
# not result:代表数据库version表中无数据
if not result:
self.get_true_link(false_link)
# 可选操作: 数据库version表中只保留最新1条数据
self.cursor.execute("delete from version")
# 把爬取后的url插入到version表中
self.cursor.execute('insert into version values(%s)', [false_link])
self.db.commit()
else:
print('数据已是最新,无须爬取')
# 获取真链接
def get_true_link(self, false_link):
# 先获取假链接的响应,然后根据响应获取真链接
html = requests.get(url=false_link, headers=self.headers).text
# 从二级页面的响应中提取真实的链接(此处为JS动态加载跳转的地址)
re_bds = r'window.location.href="(.*?)" rel="external nofollow" rel="external nofollow" '
pattern = re.compile(re_bds, re.S)
true_link = pattern.findall(html)[0]
self.save_data(true_link) # 提取真链接的数据
# 用xpath直接提取数据
def save_data(self, true_link):
html = requests.get(url=true_link, headers=self.headers).text
# 基准xpath,提取每个信息的节点列表对象
parse_html = etree.HTML(html)
tr_list = parse_html.xpath('//tr[@height="19"]')
for tr in tr_list:
code = tr.xpath('./td[2]/text()')[0].strip() # 行政区划代码
name = tr.xpath('./td[3]/text()')[0].strip() # 单位名称
print(name, code)
# 主函数
def main(self):
self.get_false_link()
if __name__ == '__main__':
spider = GovementSpider()
spider.main()
动态加载数据捕获-Ajax
特征
右键->查看没有具体数据的网页源代码
滚动鼠标滚轮或其他动作时加载
抓
F12打开控制台,选择XHR异步加载数据包,找到page action抓取网络数据包
通过XHR-->Header-->General-->Request URL获取json文件的URL地址
通过XHR-->Header-->查询字符串参数
豆瓣电影数据采集案例
目标
地址:豆瓣电影排行榜-故事
type_name=%E5%89%A7%E6%83%85&type=11&interval_id=100:90&action=
目标:抓取电影名称、电影评级
F12 数据包捕获 (XHR)
1、请求 URL(基本 URL 地址):
2、Query String Paramaters(查询参数)
# 查询参数如下:
type: 13 # 电影类型
interval_id: 100:90
action: '[{},{},{}]'
start: 0 # 每次加载电影的起始索引值
limit: 20 # 每次加载的电影数量
json文件位于以下地址:
基本 URL 地址 + 查询参数
''+'type=11&interval_id=100%3A90&action=&start=20&limit=20'
代码
import requests
import time
from fake_useragent import UserAgent
class DoubanSpider(object):
def __init__(self):
self.base_url = 'https://movie.douban.com/j/chart/top_list?'
self.i = 0
def get_html(self, params):
headers = {'User-Agent': UserAgent().random}
res = requests.get(url=self.base_url, params=params, headers=headers)
res.encoding = 'utf-8'
html = res.json() # 将json格式的字符串转为python数据类型
self.parse_html(html) # 直接调用解析函数
def parse_html(self, html):
# html: [{电影1信息},{电影2信息},{}]
item = {}
for one in html:
item['name'] = one['title'] # 电影名
item['score'] = one['score'] # 评分
item['time'] = one['release_date'] # 打印测试
# 打印显示
print(item)
self.i += 1
# 获取电影总数
def get_total(self, typ):
# 异步动态加载的数据 都可以在XHR数据抓包
url = 'https://movie.douban.com/j/chart/top_list_count?type={}&interval_id=100%3A90'.format(typ)
ua = UserAgent()
html = requests.get(url=url, headers={'User-Agent': ua.random}).json()
total = html['total']
return total
def main(self):
typ = input('请输入电影类型(剧情|喜剧|动作):')
typ_dict = {'剧情': '11', '喜剧': '24', '动作': '5'}
typ = typ_dict[typ]
total = self.get_total(typ) # 获取该类型电影总数量
for page in range(0, int(total), 20):
params = {
'type': typ,
'interval_id': '100:90',
'action': '',
'start': str(page),
'limit': '20'}
self.get_html(params)
time.sleep(1)
print('爬取的电影的数量:', self.i)
if __name__ == '__main__':
spider = DoubanSpider()
spider.main()
腾讯招聘数据抓取(Ajax)
确定 URL 地址和目标
网址:百度搜索腾讯招聘-查看职位
目标:职位名称、工作职责、工作要求
需求与分析
通过查看网页源代码,我们知道所有需要的数据都是Ajax动态加载的
通过F12捕获网络数据包进行分析
一级页面爬取数据:职位
在二级页面上抓取数据:工作职责、工作要求
一级页面的json地址(pageIndex在变化,时间戳不检查)
{}&pageSize=10&language=zh-cn&area=cn
二级页面地址(postId在变化,可以在一级页面获取)
{}&language=zh-cn
用户代理.py文件
ua_list = [
'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.163 Safari/535.1',
'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0) Gecko/20100101 Firefox/6.0',
'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; InfoPath.3)',
]
import time
import json
import random
import requests
from useragents import ua_list
class TencentSpider(object):
def __init__(self):
self.one_url = 'https://careers.tencent.com/tencentcareer/api/post/Query?timestamp=1563912271089&countryId=&cityId=&bgIds=&productId=&categoryId=&parentCategoryId=&attrId=&keyword=&pageIndex={}&pageSize=10&language=zh-cn&area=cn'
self.two_url = 'https://careers.tencent.com/tencentcareer/api/post/ByPostId?timestamp=1563912374645&postId={}&language=zh-cn'
self.f = open('tencent.json', 'a') # 打开文件
self.item_list = [] # 存放抓取的item字典数据
# 获取响应内容函数
def get_page(self, url):
headers = {'User-Agent': random.choice(ua_list)}
html = requests.get(url=url, headers=headers).text
html = json.loads(html) # json格式字符串转为Python数据类型
return html
# 主线函数: 获取所有数据
def parse_page(self, one_url):
html = self.get_page(one_url)
item = {}
for job in html['Data']['Posts']:
item['name'] = job['RecruitPostName'] # 名称
post_id = job['PostId'] # postId,拿postid为了拼接二级页面地址
# 拼接二级地址,获取职责和要求
two_url = self.two_url.format(post_id)
item['duty'], item['require'] = self.parse_two_page(two_url)
print(item)
self.item_list.append(item) # 添加到大列表中
# 解析二级页面函数
def parse_two_page(self, two_url):
html = self.get_page(two_url)
duty = html['Data']['Responsibility'] # 工作责任
duty = duty.replace('\r\n', '').replace('\n', '') # 去掉换行
require = html['Data']['Requirement'] # 工作要求
require = require.replace('\r\n', '').replace('\n', '') # 去掉换行
return duty, require
# 获取总页数
def get_numbers(self):
url = self.one_url.format(1)
html = self.get_page(url)
numbers = int(html['Data']['Count']) // 10 + 1 # 每页有10个推荐
return numbers
def main(self):
number = self.get_numbers()
for page in range(1, 3):
one_url = self.one_url.format(page)
self.parse_page(one_url)
# 保存到本地json文件:json.dump
json.dump(self.item_list, self.f, ensure_ascii=False)
self.f.close()
if __name__ == '__main__':
start = time.time()
spider = TencentSpider()
spider.main()
end = time.time()
print('执行时间:%.2f' % (end - start))
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持面圈教程。
ajax抓取网页内容(思考的问题:怎么在一个网页的div中获取部分内容)
网站优化 • 优采云 发表了文章 • 0 个评论 • 53 次浏览 • 2021-12-13 15:17
需要考虑的问题:
如何在一个网页的div中嵌套另一个网页(不使用inclue,iframe和frame,不使用的原因,include只能嵌套静态网页,iframe影响网络爬虫,frame嵌套的网页无法获取父页面信息,不够灵活)如果您不想嵌套整个网页怎么办?(只是嵌套另一页内容的一部分)
答案(想法):
使用jquery的ajax函数或者load函数获取网页内容,从而实现嵌套网页(获取的网页内容为html字符串)如何从字符串中获取部分内容?
实践一:
index.html 页面(获取本页内容页的内容)
1
2
3
4 使用jquery的ajax函数获取网页内容
5
6 div{
7 display: block;
8 }
9
10
11
12
13
14
15
16
17
18 This is index.html;
19
20
21
22
23
24
25
26
27 /*
28 * 使用ajax方式获取网页内容(也可以使用load方式获取)
29 * */
30 //解决方案一
31 function GetPageContent1(url) {
32 $.ajax({
33 type: \'get\',
34 url: url,
35 async: true,
36 success: function(html) {
37 $("#content").html(html);
38 },
39 error: function(errorMsg){
40 alert(errorMsg);
41 }
42 })
43 }
44 //解决方案二
45 function GetPageContent2(url){
46 /* 想知道更多的load方法信息,请查阅jquery api */
47 $("#content").load(url);
48 }
49
查看代码
content.html 页面
1
2
3 内容页
4
5
6
7
8 This is Content Page;
9
10
11
12
查看代码
第一个问题可以在这里解决,点击获取完整的content.html页面内容
在参考jquery的load方法的时候可以发现load函数其实可以指定网页的内容
实践二:
改变index.html页面的ajax函数的url路径,获取content.html页面的div的id=container的内容
1
2
3
4 使用jquery的ajax函数获取网页内容
5
6 div{
7 display: block;
8 }
9
10
11
12
13
14
15
16
17
18 This is index.html;
19
20
21
22
23
24
25
26
27 /*
28 * 使用ajax方式获取网页内容(也可以使用load方式获取)
29 * */
30 //解决方案一
31 function GetPageContent1(url) {
32 $.ajax({
33 type: \'get\',
34 url: url + \' #container\',
35 async: true,
36 success: function(html) {
37 $("#content").html(html);
38 },
39 error: function(errorMsg){
40 alert(errorMsg);
41 }
42 })
43 }
44 //解决方案二
45 function GetPageContent2(url){
46 /* 想知道更多的load方法信息,请查阅jquery api */
47 $("#content").load(url + \' #container\');
48 }
49
查看代码
至此我们已经解决了文章开头提出的问题。. . . . . 但这是一个静态页面(html页面),是否适用?
答案是不。无论是ajax函数还是load函数获取的页面内容,都收录title标签和两个
这是ajax获取的内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 Welcome to Content Page!
17
18
查看代码
我们可以看到不仅获取到了div的内容,还多了两个div和一个title
我在网上查了一些资料。有人说使用 $(html).find("#container").html(); 可以解决,但是实践后还是不行。以下是我的最终解决方案
这是Test1.aspx页面,相当于之前的index.html(是我命名的错误,请见谅)
1
2
3 DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DT ... gt%3B
4
5
6
7
8
9 div{
10 display: block;
11 }
12
13
14
15
16
17
18
19
20
21
22 This is index.html;
23
24
25
26
27
28
29
30
31
32 /*
33 * 使用ajax方式获取网页内容(也可以使用load方式获取)
34 * */
35 //解决方案一
36 function GetPageContent1(url) {
37 $.ajax({
38 type: \'get\',
39 //url:直接使用url将会获取到整个网页的内容
40 //url + \' #container\':获取url网页中container容器内的内容
41 url: url + \' #container\',
42 async: true,
43 success: function (html) {
44 $("#content").html($(html).find(\'div[id=container]\').html());
45
46 //$("#content").html(html);
47 },
48 error: function(errorMsg) {
49 alert(errorMsg);
50 }
51 });
52 }
53 //解决方案二(缺点是content容器会被两次赋值,如不在加载完成之后的函数中进行数据处理,讲含有title、asp.net隐藏内容等标签)
54 function GetPageContent2(url) {
55 /* 想知道更多的load方法信息,请查阅jquery api */
56 $("#content").load(url + \' #container\', \'\', function (response, status, xhr) {
57 //response#是获取到的所有数据(未被截取),status#状态,成功或者失败,xhr#包含 XMLHttpRequest 对象
58 $("#content").html($(response).find(\'div[id=container]\').html());
59 });
60 }
61
62
查看代码
内容页面.aspx
1
2
3 DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DT ... gt%3B
4
5
6
7
8
9
10
11
12 Welcome to Content Page!
13
14
15
16
17
查看代码
注意:如果直接复制代码,请修改jquery文件路径
让我再补充一点,为什么不使用母版页
使用母版页,点击菜单会刷新整个网页,使用母版页会导致标签id改变。我想要实现的是点击菜单而不刷新页面 查看全部
ajax抓取网页内容(思考的问题:怎么在一个网页的div中获取部分内容)
需要考虑的问题:
如何在一个网页的div中嵌套另一个网页(不使用inclue,iframe和frame,不使用的原因,include只能嵌套静态网页,iframe影响网络爬虫,frame嵌套的网页无法获取父页面信息,不够灵活)如果您不想嵌套整个网页怎么办?(只是嵌套另一页内容的一部分)
答案(想法):
使用jquery的ajax函数或者load函数获取网页内容,从而实现嵌套网页(获取的网页内容为html字符串)如何从字符串中获取部分内容?
实践一:
index.html 页面(获取本页内容页的内容)
1
2
3
4 使用jquery的ajax函数获取网页内容
5
6 div{
7 display: block;
8 }
9
10
11
12
13
14
15
16
17
18 This is index.html;
19
20
21
22
23
24
25
26
27 /*
28 * 使用ajax方式获取网页内容(也可以使用load方式获取)
29 * */
30 //解决方案一
31 function GetPageContent1(url) {
32 $.ajax({
33 type: \'get\',
34 url: url,
35 async: true,
36 success: function(html) {
37 $("#content").html(html);
38 },
39 error: function(errorMsg){
40 alert(errorMsg);
41 }
42 })
43 }
44 //解决方案二
45 function GetPageContent2(url){
46 /* 想知道更多的load方法信息,请查阅jquery api */
47 $("#content").load(url);
48 }
49
查看代码
content.html 页面
1
2
3 内容页
4
5
6
7
8 This is Content Page;
9
10
11
12
查看代码
第一个问题可以在这里解决,点击获取完整的content.html页面内容
在参考jquery的load方法的时候可以发现load函数其实可以指定网页的内容
实践二:
改变index.html页面的ajax函数的url路径,获取content.html页面的div的id=container的内容
1
2
3
4 使用jquery的ajax函数获取网页内容
5
6 div{
7 display: block;
8 }
9
10
11
12
13
14
15
16
17
18 This is index.html;
19
20
21
22
23
24
25
26
27 /*
28 * 使用ajax方式获取网页内容(也可以使用load方式获取)
29 * */
30 //解决方案一
31 function GetPageContent1(url) {
32 $.ajax({
33 type: \'get\',
34 url: url + \' #container\',
35 async: true,
36 success: function(html) {
37 $("#content").html(html);
38 },
39 error: function(errorMsg){
40 alert(errorMsg);
41 }
42 })
43 }
44 //解决方案二
45 function GetPageContent2(url){
46 /* 想知道更多的load方法信息,请查阅jquery api */
47 $("#content").load(url + \' #container\');
48 }
49
查看代码
至此我们已经解决了文章开头提出的问题。. . . . . 但这是一个静态页面(html页面),是否适用?
答案是不。无论是ajax函数还是load函数获取的页面内容,都收录title标签和两个
这是ajax获取的内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 Welcome to Content Page!
17
18
查看代码
我们可以看到不仅获取到了div的内容,还多了两个div和一个title
我在网上查了一些资料。有人说使用 $(html).find("#container").html(); 可以解决,但是实践后还是不行。以下是我的最终解决方案
这是Test1.aspx页面,相当于之前的index.html(是我命名的错误,请见谅)
1
2
3 DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DT ... gt%3B
4
5
6
7
8
9 div{
10 display: block;
11 }
12
13
14
15
16
17
18
19
20
21
22 This is index.html;
23
24
25
26
27
28
29
30
31
32 /*
33 * 使用ajax方式获取网页内容(也可以使用load方式获取)
34 * */
35 //解决方案一
36 function GetPageContent1(url) {
37 $.ajax({
38 type: \'get\',
39 //url:直接使用url将会获取到整个网页的内容
40 //url + \' #container\':获取url网页中container容器内的内容
41 url: url + \' #container\',
42 async: true,
43 success: function (html) {
44 $("#content").html($(html).find(\'div[id=container]\').html());
45
46 //$("#content").html(html);
47 },
48 error: function(errorMsg) {
49 alert(errorMsg);
50 }
51 });
52 }
53 //解决方案二(缺点是content容器会被两次赋值,如不在加载完成之后的函数中进行数据处理,讲含有title、asp.net隐藏内容等标签)
54 function GetPageContent2(url) {
55 /* 想知道更多的load方法信息,请查阅jquery api */
56 $("#content").load(url + \' #container\', \'\', function (response, status, xhr) {
57 //response#是获取到的所有数据(未被截取),status#状态,成功或者失败,xhr#包含 XMLHttpRequest 对象
58 $("#content").html($(response).find(\'div[id=container]\').html());
59 });
60 }
61
62
查看代码
内容页面.aspx
1
2
3 DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DT ... gt%3B
4
5
6
7
8
9
10
11
12 Welcome to Content Page!
13
14
15
16
17
查看代码
注意:如果直接复制代码,请修改jquery文件路径
让我再补充一点,为什么不使用母版页
使用母版页,点击菜单会刷新整个网页,使用母版页会导致标签id改变。我想要实现的是点击菜单而不刷新页面
ajax抓取网页内容(【投稿】本文中爬虫常用的库,用之前需要先下载好)
网站优化 • 优采云 发表了文章 • 0 个评论 • 65 次浏览 • 2021-12-13 05:02
本文是读者提交的第二篇文章。如果你想投稿,可以后台联系我。作者:parkson知乎:喜欢的可以关注,点击原文直接阅读。
本文的一般路线
首先列出一些python中爬虫常用的库。您需要先下载它们,然后才能使用它们。本文假设您已经安装了相应的库。
下载库:
0、Urllib 库
1、requests 在发出请求时使用
2、将使用selenium自动化
解析库:
3、正则匹配重新解析网页
4、用于Xpath的lxml第三方库
5、beautifulSoup 解析网页
6、pyquery 网页解析库类似于beautifulSoup
数据库操作库:
7、pymysql 操作mysql数据
8、pymongo 操作MongoDB数据库
9、redis 非关系型数据库
10、jupyter 在线笔记本
一、 Ajax的简单理解
1、AJAX是一种技术,一种创建快速动态网页的技术;不是一种新的编程语言,而是一种使用现有标准的新方法。
2、AJAX=Asynchronous JavaScript and XML(异步 JavaScript 和 XML)
3、AJAX 是与服务器交换数据并更新部分网页的艺术,在不重新加载整个页面的情况下更新网页的某个部分。如果需要更新传统网页的内容(不使用 AJAX),则必须重新加载整个网页。
4、 Ajax 技术的核心是 XMLHttpRequest 对象(简称 XHR,即 AJAX 创建一个 XMLHttpRequest 对象并向服务器发送请求),它可以使用 XHR 对象从服务器获取数据,然后通过DOM Presentation将数据插入页面(AJAX加载的数据由浏览器渲染显示)。虽然名称中收录XML,但Ajax通信与数据格式无关(它是网页制作中的一种方法和技术),因此我们的数据格式可以是XML或JSON等格式。
二、 爬行AJAX动态加载网页案例
爬虫,简单的说就是自动从网上下载你感兴趣的信息。一般分为下载和解析两个步骤。
Ajax一般返回json格式的数据,直接用requests来post或获取(下载)ajax地址,返回json格式的数据,解析json数据得到你想要的信息(分析)。
如果我们使用AJAX加载的动态网页,我们如何抓取动态加载的内容?一般有两种方法:
方法一、通过selenium模拟浏览器爬行
方法二、通过浏览器review元素解析地址
case 一、URL保持不变,tab中第二个请求的URL按照一定的规则变化
以豆瓣电影为例:#/?sort=T&range=0,10&tags=%E5%8A%B1%E5%BF%97,点击加载更多刷新页面。
方法一、通过selenium模拟浏览器爬行,Beautiful Soup解析网页
这里有两种请求方式,设置一定的点击次数,不断点击加载更多
##设置一定的点击次数
from bs4 import BeautifulSoup
from selenium import webdriver
import time
import re
browser = webdriver.Chrome()###版本 68.0.3440.106(正式版本) (64 位)
browser.get('https://movie.douban.com/tag/#/?sort=T&range=0,10&tags=')
browser.implicitly_wait(3)##浏览器解释JS脚本是需要时间的,但实际上这个时间并不好确定,如果我们手动设定时间间隔的话,设置多了浪费时间,设置少了又会丢失数据
##implictly_wait函数则完美解决了这个问题,给他一个时间参数,它会只能等待,当js完全解释完毕就会自动执行下一步。
time.sleep(3)
browser.find_element_by_xpath('//*[@id="app"]/div/div[1]/div[1]/ul[4]/li[6]/span').click()###自动选择励志电影类型
i = 0
for i in range(5):##这里设置点击5次“加载更多”
browser.find_element_by_link_text("加载更多").click()
time.sleep(5)###如果网页没有完全加载,会出现点击错误,会点击到某个电影页面,所以加了一个睡眠时间。
##browswe.page_source是点击5次后的源码,用Beautiful Soup解析源码
soup = BeautifulSoup(browser.page_source, 'html.parser')
items = soup.find('div', class_=re.compile('list-wp'))
for item in items.find_all('a'):
Title = item.find('span', class_='title').text
Rate = item.find('span', class_='rate').text
Link = item.find('span',class_='pic').find('img').get('src')
print(Title,Rate,Link)
------------------------------------------------------------------------------------------------
###一直不断点击,直到加载完全
from bs4 import BeautifulSoup
from selenium import webdriver
import time
import re
browser = webdriver.Chrome()###版本 68.0.3440.106(正式版本) (64 位)
browser.get('https://movie.douban.com/tag/#/?sort=T&range=0,10&tags=')
browser.implicitly_wait(3)
time.sleep(3)
browser.find_element_by_xpath('//*[@id="app"]/div/div[1]/div[1]/ul[4]/li[6]/span').click()###自动选择励志电影类型
soup = BeautifulSoup(browser.page_source, 'html.parser')
while len(soup.select('.more'))>0:##soup.select(),返回类型是 list,判断只要长度大于0,就会一直不断点击。
browser.find_element_by_link_text("加载更多").click()
time.sleep(5)###如果网页没有完全加载,会出现点击错误,会点击到某个电影页面,所以加了一个睡眠时间。
soup = BeautifulSoup(browser.page_source, 'html.parser')
##将 加载更多 全部点击完成后,用Beautiful Soup解析网页源代码
items = soup.find('div', class_=re.compile('list-wp'))
for item in items.find_all('a'):
Title = item.find('span', class_='title').text
Rate = item.find('span', class_='rate').text
Link = item.find('span', class_='pic').find('img').get('src')
print(Title, Rate, Link)
方法二、直接根据tab中的URL规则构造第二个请求的URL
该网页通过 ajax 加载,一次显示 20 部电影。
点击加载更多
在Network选项卡中可以发现多了一个new_search,就是点击加载更多后需要重新加载的页面。对比几个new_searches,你会发现Request URL的结尾是start=i,i总是20的倍数,这样就可以直接写一个循环爬取多页电影信息了。
import requests
from requests.exceptions import RequestException
import time
import csv
import json
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'}
def get_one_page(url):
try:
response = requests.get(url,headers=headers)
if response.status_code == 200:
return response.json()##将返回的json数据转换为python可读的字典数据,.json是requests库自带的函数。
return None
except RequestException:
print("抓取失败")
def parse_one_page(d):
try:
datum = d['data']
for data in datum:
yield{
'Title':data['title'],
'Director':data['directors'],
'Actors':data['casts'],
'Rate':data['rate'],
'Link':data['url']
}
if data['Title','Director','Actors','Rate','Link'] == None:
return None
except Exception:
return None
def main():
for i in range(10):###这里就抓取10个网页,如果需求更多数据,将将数字改更大些即可。
url = 'https://movie.douban.com/j/new ... e%3D0,10&tags=%E5%8A%B1%E5%BF%97&start={}'.format(i*20)
d = get_one_page(url)
print('第{}页抓取完毕'.format(i+1))
for item in parse_one_page(d):
print(item)
##将输出字典依次写入csv文件中
with open('Movie.csv', 'a', newline='',encoding='utf-8') as f: # file_path 是 csv 文件存储的路径,默认路径
fieldnames = ['Title', 'Director', 'Actors', 'Rate', 'Link']
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
for item in parse_one_page(d):
writer.writerow(item)
if __name__=='__main__':
main()
case 二、URL不变,tab中第二个请求的URL不规则
以CSDN网站为例,抓取CSDN首页文章列表:CSDN-专业IT技术社区 当CSDN-专业IT技术社区下拉时URL保持不变,第二次请求的URL标签中不规则,网页下拉刷新。
方法一、通过selenium模拟浏览器爬行,用正则表达式解析网页
from selenium import webdriver
import re
import time
browser = webdriver.Chrome()
browser.get('https://www.csdn.net/')
browser.implicitly_wait(10)
i = 0
for i in range(5):###设置下拉5次,如果想获取更多信息,增加下拉次数即可
browser.execute_script('window.scrollTo(0, document.body.scrollHeight)')##下拉,execute_script可以将进度条下拉到最底部
time.sleep(5)##睡眠一下,防止网络延迟,卡顿等
data = []
pattern = re.compile('.*?(.*?)</a>.*?(.*?)</a>'
'.*?(.*?).*?',re.S)
items = re.findall(pattern,browser.page_source)##这里网页源代码为下拉5次后的代码
for item in items:
data.append({
'Title':item[0].strip(),
'Author' : item[1].strip(),
'ReadNum' : item[2] + item[3]
})
print(data)
方法二、通过浏览器review元素解析真实地址
import requests
headers = {'cookie':'uuid_tt_dd=3844871280714138949_20171108; kd_user_id=e61e2f88-9c4f-4cf7-88c7-68213cac17f7; UN=qq_40963426; BT=1521452212412; Hm_ct_6bcd52f51e9b3dce32bec4a3997715ac=1788*1*PC_VC; smidV2=20180626144357b069d2909d23ff73c3bc90ce183c8c57003acfcec7f57dd70; __utma=17226283.14643699.1533350144.1533350144.1534431588.2; __utmz=17226283.1533350144.1.1.utmcsr=zhuanlan.zhihu.com|utmccn=(referral)|utmcmd=referral|utmcct=/p/39165199/edit; TY_SESSION_ID=f49bdedd-c1d4-4f86-b254-22ab2e8f02f6; ViewMode=contents; UM_distinctid=165471259cb3e-02c5602643907b-5d4e211f-100200-165471259cc86; dc_session_id=10_1534471423488.794042; dc_tos=pdlzzq; Hm_lvt_6bcd52f51e9b3dce32bec4a3997715ac=1534515139,1534515661,1534515778,1534515830; Hm_lpvt_6bcd52f51e9b3dce32bec4a3997715ac=1534515830; ADHOC_MEMBERSHIP_CLIENT_ID1.0=d480c872-d4e9-33d9-d0e5-f076fc76aa83',
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'}
def get_page():
r =requests.get('https://www.csdn.net/api/artic ... 27%3B,headers=headers)
d=r.json()#一般ajax返回的都是json格式数据,将返回的数据json格式化,.json()是requests库自带函数
articles = d['articles']#字典形式
for article in articles:
yield {
'article':article['title'],
'Link':article['user_url'],
'View':article['views']
}
for i in get_page():
print(i)
##这里应该有关于抓取不同页文章标题的操作,但是还没有解决。
案例二参考链接:
注意:CSDN爬取基础咨询需要注意会有top信息,使用selenium+Beautiful Soup或者xpath解析时需要单独注意,否则代码会一直报错。
不管是静态网页还是动态网页,爬虫的核心都是下载和解析。 查看全部
ajax抓取网页内容(【投稿】本文中爬虫常用的库,用之前需要先下载好)
本文是读者提交的第二篇文章。如果你想投稿,可以后台联系我。作者:parkson知乎:喜欢的可以关注,点击原文直接阅读。
本文的一般路线
首先列出一些python中爬虫常用的库。您需要先下载它们,然后才能使用它们。本文假设您已经安装了相应的库。
下载库:
0、Urllib 库
1、requests 在发出请求时使用
2、将使用selenium自动化
解析库:
3、正则匹配重新解析网页
4、用于Xpath的lxml第三方库
5、beautifulSoup 解析网页
6、pyquery 网页解析库类似于beautifulSoup
数据库操作库:
7、pymysql 操作mysql数据
8、pymongo 操作MongoDB数据库
9、redis 非关系型数据库
10、jupyter 在线笔记本
一、 Ajax的简单理解
1、AJAX是一种技术,一种创建快速动态网页的技术;不是一种新的编程语言,而是一种使用现有标准的新方法。
2、AJAX=Asynchronous JavaScript and XML(异步 JavaScript 和 XML)
3、AJAX 是与服务器交换数据并更新部分网页的艺术,在不重新加载整个页面的情况下更新网页的某个部分。如果需要更新传统网页的内容(不使用 AJAX),则必须重新加载整个网页。
4、 Ajax 技术的核心是 XMLHttpRequest 对象(简称 XHR,即 AJAX 创建一个 XMLHttpRequest 对象并向服务器发送请求),它可以使用 XHR 对象从服务器获取数据,然后通过DOM Presentation将数据插入页面(AJAX加载的数据由浏览器渲染显示)。虽然名称中收录XML,但Ajax通信与数据格式无关(它是网页制作中的一种方法和技术),因此我们的数据格式可以是XML或JSON等格式。
二、 爬行AJAX动态加载网页案例
爬虫,简单的说就是自动从网上下载你感兴趣的信息。一般分为下载和解析两个步骤。
Ajax一般返回json格式的数据,直接用requests来post或获取(下载)ajax地址,返回json格式的数据,解析json数据得到你想要的信息(分析)。
如果我们使用AJAX加载的动态网页,我们如何抓取动态加载的内容?一般有两种方法:
方法一、通过selenium模拟浏览器爬行
方法二、通过浏览器review元素解析地址
case 一、URL保持不变,tab中第二个请求的URL按照一定的规则变化
以豆瓣电影为例:#/?sort=T&range=0,10&tags=%E5%8A%B1%E5%BF%97,点击加载更多刷新页面。
方法一、通过selenium模拟浏览器爬行,Beautiful Soup解析网页
这里有两种请求方式,设置一定的点击次数,不断点击加载更多
##设置一定的点击次数
from bs4 import BeautifulSoup
from selenium import webdriver
import time
import re
browser = webdriver.Chrome()###版本 68.0.3440.106(正式版本) (64 位)
browser.get('https://movie.douban.com/tag/#/?sort=T&range=0,10&tags=')
browser.implicitly_wait(3)##浏览器解释JS脚本是需要时间的,但实际上这个时间并不好确定,如果我们手动设定时间间隔的话,设置多了浪费时间,设置少了又会丢失数据
##implictly_wait函数则完美解决了这个问题,给他一个时间参数,它会只能等待,当js完全解释完毕就会自动执行下一步。
time.sleep(3)
browser.find_element_by_xpath('//*[@id="app"]/div/div[1]/div[1]/ul[4]/li[6]/span').click()###自动选择励志电影类型
i = 0
for i in range(5):##这里设置点击5次“加载更多”
browser.find_element_by_link_text("加载更多").click()
time.sleep(5)###如果网页没有完全加载,会出现点击错误,会点击到某个电影页面,所以加了一个睡眠时间。
##browswe.page_source是点击5次后的源码,用Beautiful Soup解析源码
soup = BeautifulSoup(browser.page_source, 'html.parser')
items = soup.find('div', class_=re.compile('list-wp'))
for item in items.find_all('a'):
Title = item.find('span', class_='title').text
Rate = item.find('span', class_='rate').text
Link = item.find('span',class_='pic').find('img').get('src')
print(Title,Rate,Link)
------------------------------------------------------------------------------------------------
###一直不断点击,直到加载完全
from bs4 import BeautifulSoup
from selenium import webdriver
import time
import re
browser = webdriver.Chrome()###版本 68.0.3440.106(正式版本) (64 位)
browser.get('https://movie.douban.com/tag/#/?sort=T&range=0,10&tags=')
browser.implicitly_wait(3)
time.sleep(3)
browser.find_element_by_xpath('//*[@id="app"]/div/div[1]/div[1]/ul[4]/li[6]/span').click()###自动选择励志电影类型
soup = BeautifulSoup(browser.page_source, 'html.parser')
while len(soup.select('.more'))>0:##soup.select(),返回类型是 list,判断只要长度大于0,就会一直不断点击。
browser.find_element_by_link_text("加载更多").click()
time.sleep(5)###如果网页没有完全加载,会出现点击错误,会点击到某个电影页面,所以加了一个睡眠时间。
soup = BeautifulSoup(browser.page_source, 'html.parser')
##将 加载更多 全部点击完成后,用Beautiful Soup解析网页源代码
items = soup.find('div', class_=re.compile('list-wp'))
for item in items.find_all('a'):
Title = item.find('span', class_='title').text
Rate = item.find('span', class_='rate').text
Link = item.find('span', class_='pic').find('img').get('src')
print(Title, Rate, Link)
方法二、直接根据tab中的URL规则构造第二个请求的URL
该网页通过 ajax 加载,一次显示 20 部电影。
点击加载更多
在Network选项卡中可以发现多了一个new_search,就是点击加载更多后需要重新加载的页面。对比几个new_searches,你会发现Request URL的结尾是start=i,i总是20的倍数,这样就可以直接写一个循环爬取多页电影信息了。
import requests
from requests.exceptions import RequestException
import time
import csv
import json
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'}
def get_one_page(url):
try:
response = requests.get(url,headers=headers)
if response.status_code == 200:
return response.json()##将返回的json数据转换为python可读的字典数据,.json是requests库自带的函数。
return None
except RequestException:
print("抓取失败")
def parse_one_page(d):
try:
datum = d['data']
for data in datum:
yield{
'Title':data['title'],
'Director':data['directors'],
'Actors':data['casts'],
'Rate':data['rate'],
'Link':data['url']
}
if data['Title','Director','Actors','Rate','Link'] == None:
return None
except Exception:
return None
def main():
for i in range(10):###这里就抓取10个网页,如果需求更多数据,将将数字改更大些即可。
url = 'https://movie.douban.com/j/new ... e%3D0,10&tags=%E5%8A%B1%E5%BF%97&start={}'.format(i*20)
d = get_one_page(url)
print('第{}页抓取完毕'.format(i+1))
for item in parse_one_page(d):
print(item)
##将输出字典依次写入csv文件中
with open('Movie.csv', 'a', newline='',encoding='utf-8') as f: # file_path 是 csv 文件存储的路径,默认路径
fieldnames = ['Title', 'Director', 'Actors', 'Rate', 'Link']
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
for item in parse_one_page(d):
writer.writerow(item)
if __name__=='__main__':
main()
case 二、URL不变,tab中第二个请求的URL不规则
以CSDN网站为例,抓取CSDN首页文章列表:CSDN-专业IT技术社区 当CSDN-专业IT技术社区下拉时URL保持不变,第二次请求的URL标签中不规则,网页下拉刷新。
方法一、通过selenium模拟浏览器爬行,用正则表达式解析网页
from selenium import webdriver
import re
import time
browser = webdriver.Chrome()
browser.get('https://www.csdn.net/')
browser.implicitly_wait(10)
i = 0
for i in range(5):###设置下拉5次,如果想获取更多信息,增加下拉次数即可
browser.execute_script('window.scrollTo(0, document.body.scrollHeight)')##下拉,execute_script可以将进度条下拉到最底部
time.sleep(5)##睡眠一下,防止网络延迟,卡顿等
data = []
pattern = re.compile('.*?(.*?)</a>.*?(.*?)</a>'
'.*?(.*?).*?',re.S)
items = re.findall(pattern,browser.page_source)##这里网页源代码为下拉5次后的代码
for item in items:
data.append({
'Title':item[0].strip(),
'Author' : item[1].strip(),
'ReadNum' : item[2] + item[3]
})
print(data)
方法二、通过浏览器review元素解析真实地址
import requests
headers = {'cookie':'uuid_tt_dd=3844871280714138949_20171108; kd_user_id=e61e2f88-9c4f-4cf7-88c7-68213cac17f7; UN=qq_40963426; BT=1521452212412; Hm_ct_6bcd52f51e9b3dce32bec4a3997715ac=1788*1*PC_VC; smidV2=20180626144357b069d2909d23ff73c3bc90ce183c8c57003acfcec7f57dd70; __utma=17226283.14643699.1533350144.1533350144.1534431588.2; __utmz=17226283.1533350144.1.1.utmcsr=zhuanlan.zhihu.com|utmccn=(referral)|utmcmd=referral|utmcct=/p/39165199/edit; TY_SESSION_ID=f49bdedd-c1d4-4f86-b254-22ab2e8f02f6; ViewMode=contents; UM_distinctid=165471259cb3e-02c5602643907b-5d4e211f-100200-165471259cc86; dc_session_id=10_1534471423488.794042; dc_tos=pdlzzq; Hm_lvt_6bcd52f51e9b3dce32bec4a3997715ac=1534515139,1534515661,1534515778,1534515830; Hm_lpvt_6bcd52f51e9b3dce32bec4a3997715ac=1534515830; ADHOC_MEMBERSHIP_CLIENT_ID1.0=d480c872-d4e9-33d9-d0e5-f076fc76aa83',
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'}
def get_page():
r =requests.get('https://www.csdn.net/api/artic ... 27%3B,headers=headers)
d=r.json()#一般ajax返回的都是json格式数据,将返回的数据json格式化,.json()是requests库自带函数
articles = d['articles']#字典形式
for article in articles:
yield {
'article':article['title'],
'Link':article['user_url'],
'View':article['views']
}
for i in get_page():
print(i)
##这里应该有关于抓取不同页文章标题的操作,但是还没有解决。
案例二参考链接:
注意:CSDN爬取基础咨询需要注意会有top信息,使用selenium+Beautiful Soup或者xpath解析时需要单独注意,否则代码会一直报错。
不管是静态网页还是动态网页,爬虫的核心都是下载和解析。
ajax抓取网页内容(越来越多的网站采用Ajax技术解决方法放弃井号结构)
网站优化 • 优采云 发表了文章 • 0 个评论 • 42 次浏览 • 2021-12-13 04:28
越来越多的网站开始采用“单页应用”。
整个网站只有一个网页,利用Ajax技术根据用户的输入加载不同的内容。
这种方式的优点是用户体验好,节省流量。缺点是AJAX内容无法被搜索引擎抓取。例如,您有一个 网站。
用户可以通过带有哈希结构的 URL 看到不同的内容。
#1
#2
#3
但是,搜索引擎只会抓取并忽略井号,因此它们无法索引内容。
为了解决这个问题,谷歌提出了“哈希+感叹号”的结构。
#!1
当谷歌找到上述网址时,它会自动抓取另一个网址:
只要你把 AJAX 内容放到这个 URL 上,Google 就会收录。但问题是“哈希+感叹号”非常丑陋和繁琐。Twitter曾经使用这种结构,它把
改成
#!/ruanyf
结果,用户抱怨连连,只用了半年时间就废了。
那么,有没有什么办法可以让搜索引擎在保持一个更直观的URL的同时抓取AJAX内容呢?
一直觉得没办法,直到前两天看到一位Discourse创始人的解决方案,忍不住尖叫起来。
Discourse 是一个严重依赖 Ajax 的论坛程序,但它必须让 Google收录 内容。它的解决方案是放弃hash结构,使用History API。
所谓History API,就是在不刷新页面的情况下,改变浏览器地址栏中显示的URL(准确的说是改变网页的当前状态)。这是一个示例,您单击上面的按钮开始播放音乐。然后,点击下面的链接,地址栏中的URL变了,但音乐播放没有中断!
History API 的详细介绍超出了本文章的范围。简单的说到这里,它的作用就是给浏览器的History对象添加一条记录。
window.history.pushState(state object, title, url);
上面这行命令可以让地址栏中出现一个新的 URL。History对象的pushState方法接受三个参数,新的URL为第三个参数,前两个参数可以为null。
window.history.pushState(null, null, newURL);
目前主流浏览器都支持这种方式:Chrome(26.0+)、Firefox(20.0+)、IE(10.0+)、Safari(5.1+)、歌剧 (12.1+)。
这是罗宾沃德的方法。
首先用History API替换hash结构,让每一个hash符号变成一个正常路径的URL,这样搜索引擎就会抓取每一个网页。
/1
/2
/3
然后,定义一个 JavaScript 函数来处理 Ajax 部分并根据 URL 抓取内容(假设使用 jQuery)。
功能锚点击(链接){
var linkSplit = link.split('/').pop();
$.get('api/' + linkSplit, function(data) {
$('#content').html(数据);
});
}
然后定义鼠标的点击事件。
$('#container').on('click','a', function(e) {
window.history.pushState(null, null, $(this).attr('href'));
anchorClick($(this).attr('href'));
e.preventDefault();
});
还要考虑用户点击浏览器的“前进/后退”按钮。这时候会触发History对象的popstate事件。
window.addEventListener('popstate', function(e) {
锚点击(位置。路径名);
});
定义以上三段代码后,无需刷新页面即可显示正常路径URL和AJAX内容。
最后,设置服务器端。
因为没有使用 hashtag 结构,所以每个 URL 都是不同的请求。因此,服务器需要向所有这些请求返回具有以下结构的网页,以防止 404 错误。
如果你仔细看上面的代码,你会发现里面有一个 noscript 标签。这就是秘密。
我们将所有我们想要搜索引擎的内容放在了 noscript 标签中。在这种情况下,用户仍然可以在不刷新页面的情况下进行AJAX操作,但是搜索引擎会收录每个页面的主要内容! 查看全部
ajax抓取网页内容(越来越多的网站采用Ajax技术解决方法放弃井号结构)
越来越多的网站开始采用“单页应用”。
整个网站只有一个网页,利用Ajax技术根据用户的输入加载不同的内容。
这种方式的优点是用户体验好,节省流量。缺点是AJAX内容无法被搜索引擎抓取。例如,您有一个 网站。
用户可以通过带有哈希结构的 URL 看到不同的内容。
#1
#2
#3
但是,搜索引擎只会抓取并忽略井号,因此它们无法索引内容。
为了解决这个问题,谷歌提出了“哈希+感叹号”的结构。
#!1
当谷歌找到上述网址时,它会自动抓取另一个网址:
只要你把 AJAX 内容放到这个 URL 上,Google 就会收录。但问题是“哈希+感叹号”非常丑陋和繁琐。Twitter曾经使用这种结构,它把
改成
#!/ruanyf
结果,用户抱怨连连,只用了半年时间就废了。
那么,有没有什么办法可以让搜索引擎在保持一个更直观的URL的同时抓取AJAX内容呢?
一直觉得没办法,直到前两天看到一位Discourse创始人的解决方案,忍不住尖叫起来。
Discourse 是一个严重依赖 Ajax 的论坛程序,但它必须让 Google收录 内容。它的解决方案是放弃hash结构,使用History API。
所谓History API,就是在不刷新页面的情况下,改变浏览器地址栏中显示的URL(准确的说是改变网页的当前状态)。这是一个示例,您单击上面的按钮开始播放音乐。然后,点击下面的链接,地址栏中的URL变了,但音乐播放没有中断!
History API 的详细介绍超出了本文章的范围。简单的说到这里,它的作用就是给浏览器的History对象添加一条记录。
window.history.pushState(state object, title, url);
上面这行命令可以让地址栏中出现一个新的 URL。History对象的pushState方法接受三个参数,新的URL为第三个参数,前两个参数可以为null。
window.history.pushState(null, null, newURL);
目前主流浏览器都支持这种方式:Chrome(26.0+)、Firefox(20.0+)、IE(10.0+)、Safari(5.1+)、歌剧 (12.1+)。
这是罗宾沃德的方法。
首先用History API替换hash结构,让每一个hash符号变成一个正常路径的URL,这样搜索引擎就会抓取每一个网页。
/1
/2
/3
然后,定义一个 JavaScript 函数来处理 Ajax 部分并根据 URL 抓取内容(假设使用 jQuery)。
功能锚点击(链接){
var linkSplit = link.split('/').pop();
$.get('api/' + linkSplit, function(data) {
$('#content').html(数据);
});
}
然后定义鼠标的点击事件。
$('#container').on('click','a', function(e) {
window.history.pushState(null, null, $(this).attr('href'));
anchorClick($(this).attr('href'));
e.preventDefault();
});
还要考虑用户点击浏览器的“前进/后退”按钮。这时候会触发History对象的popstate事件。
window.addEventListener('popstate', function(e) {
锚点击(位置。路径名);
});
定义以上三段代码后,无需刷新页面即可显示正常路径URL和AJAX内容。
最后,设置服务器端。
因为没有使用 hashtag 结构,所以每个 URL 都是不同的请求。因此,服务器需要向所有这些请求返回具有以下结构的网页,以防止 404 错误。
如果你仔细看上面的代码,你会发现里面有一个 noscript 标签。这就是秘密。
我们将所有我们想要搜索引擎的内容放在了 noscript 标签中。在这种情况下,用户仍然可以在不刷新页面的情况下进行AJAX操作,但是搜索引擎会收录每个页面的主要内容!
ajax抓取网页内容(这是网页中元素与打印的简单对应关系-安亲宝)
网站优化 • 优采云 发表了文章 • 0 个评论 • 42 次浏览 • 2021-12-09 21:09
目前,浏览器对于网页页眉页脚的打印还存在很大的不足。可能有一些方法可以借助css来修复fixed position或者flexlayout,但是效果并不理想。
不过在最近更新的chrome to table打印中,增加了对等价元素的优化支持,解决了表格中标题和内容会被截断的问题。其实我们可以利用这个特性简单的打印页眉页脚。
这是网页中 HTML 元素和打印之间的简单对应关系:
______________________
| 头 | 标题
|____________|
| |
| | 内容
| 身体 |
| |
| |
|____________|
| 脚 | 页脚
|____________|
HTML代码示例:
这是页头? 列1 列2 FOX JUMP A RIVER GO AWAY 这是页脚
生产环境下测试效果:
目前在用Chrome打印时发现的一些问题:
1) Thead 和 tfoot 只有在表格内容超过一页时才会起作用。
2) 当内容短于一页时,tfoot中的内容将不会显示在页面底部。
3) 页面多时,页面底部不显示最后一页的tfoot
总体来说效果比之前好很多,还可以接受。网页基本可以达到和打印机软件一样的效果。 查看全部
ajax抓取网页内容(这是网页中元素与打印的简单对应关系-安亲宝)
目前,浏览器对于网页页眉页脚的打印还存在很大的不足。可能有一些方法可以借助css来修复fixed position或者flexlayout,但是效果并不理想。
不过在最近更新的chrome to table打印中,增加了对等价元素的优化支持,解决了表格中标题和内容会被截断的问题。其实我们可以利用这个特性简单的打印页眉页脚。
这是网页中 HTML 元素和打印之间的简单对应关系:
______________________
| 头 | 标题
|____________|
| |
| | 内容
| 身体 |
| |
| |
|____________|
| 脚 | 页脚
|____________|
HTML代码示例:
这是页头? 列1 列2 FOX JUMP A RIVER GO AWAY 这是页脚
生产环境下测试效果:

目前在用Chrome打印时发现的一些问题:
1) Thead 和 tfoot 只有在表格内容超过一页时才会起作用。
2) 当内容短于一页时,tfoot中的内容将不会显示在页面底部。
3) 页面多时,页面底部不显示最后一页的tfoot
总体来说效果比之前好很多,还可以接受。网页基本可以达到和打印机软件一样的效果。
ajax抓取网页内容(获取JavaScript脚本可以设计响应信息为JavaScript代码,它是可以执行的命令或脚本)
网站优化 • 优采云 发表了文章 • 0 个评论 • 48 次浏览 • 2021-12-05 17:22
获取 JavaScript 脚本
响应信息可以设计为 JavaScript 代码。这里的代码不同于 JSON 数据。它是可以执行的命令或脚本。
例子:在服务端指定JS函数
AJAX测试
按钮
function f() {
var ajax = createXMLHTTPObject();
ajax.onreadystatechange = function(){
if(ajax.readyState == 4 && ajax.status == 200){
var info = ajax.responseText;
var o = eval("(" + info + ")" + "()");//调用eval()方法把JavaScript字符串转换为本地脚本
alert(o);//返回客户端当前日期
}
}
ajax.open("get", "response.js",true);
ajax.send();
}
响应.js:
function (){
var d = new Date();
return d.toString();
}
点击按钮,会弹出提示信息:
注意:转换时需要在字符串签名后加两个括号:一个收录函数结构,一个表示调用函数。通常,JavaScript 代码很少用作响应信息的格式,因为它无法传递更丰富的信息,并且 JavaScript 脚本容易存在安全风险。 查看全部
ajax抓取网页内容(获取JavaScript脚本可以设计响应信息为JavaScript代码,它是可以执行的命令或脚本)
获取 JavaScript 脚本
响应信息可以设计为 JavaScript 代码。这里的代码不同于 JSON 数据。它是可以执行的命令或脚本。
例子:在服务端指定JS函数
AJAX测试
按钮
function f() {
var ajax = createXMLHTTPObject();
ajax.onreadystatechange = function(){
if(ajax.readyState == 4 && ajax.status == 200){
var info = ajax.responseText;
var o = eval("(" + info + ")" + "()");//调用eval()方法把JavaScript字符串转换为本地脚本
alert(o);//返回客户端当前日期
}
}
ajax.open("get", "response.js",true);
ajax.send();
}
响应.js:
function (){
var d = new Date();
return d.toString();
}
点击按钮,会弹出提示信息:

注意:转换时需要在字符串签名后加两个括号:一个收录函数结构,一个表示调用函数。通常,JavaScript 代码很少用作响应信息的格式,因为它无法传递更丰富的信息,并且 JavaScript 脚本容易存在安全风险。