Python爬虫三种解析方式,Pyhton360搜索排名查询
python爬虫中有三种解析网页的方式,正则表达式,bs4以及xpath,比较受用户喜爱的是bs4以及xpath,后期使用频率较高的是xpath,因为Scrapy框架默认使用的就是xpath解析网页数据。
数据解析方式
- 正则
- xpath
- bs4
正则 数据解析的原理:
- 标签的定位
- 提取标签中存储的文本数据或者标签属性中存储的数据
bs4解析
-
解析原理:
- 实例化一个Beautifulsoup的对象,且将页面源码数据加载到该对象中
- 使用该对象的相关属性和方法实现标签定位和数据提取
-
环境的安装:
- pip install bs4
- pip install lxml
-
实例化Beautifulsoup对象
- BeautifulSoup(page_text,'lxml'):将从互联网上请求到的页面源码数据加载到该对象中
- BeautifulSoup(fp,'lxml'):将本地存储的一样页面源码数据加载到该对象中
- 属性
soup.a.attrs 返回一字典,里面是所有属性和值
soup.a['href'] 获取href属性
soup.a.string
soup.a.text
soup.a.get_text()
xpath解析:
- 解析效率比较高
- 通用性最强的
- 环境安装:pip install lxml
- 解析原理:
- 实例化一个etree对象且将即将被解析的页面源码数据加载到该对象中
- 使用etree对象中的xpath方法结合着xpath表达式进行标签定位和数据提取
- 实例化etree对象
- etree.parse('本地文件路径')
- etree.HTML(page_text)
在网页数据解析当中,re正则解析是比较费劲的,而且非常容易出错,网页数据结构一旦出错,则容易报出异常,而且想要匹配好正则,你的正则表达式需要熟练,不然你得一步步去尝试了,某些网页数据解析还真的只能用正则表达式去匹配。
如果你有接触过火车头采集器,那么对于正则,应该不会陌生!
实例的方式为大家展示Python爬虫三种解析方式
Pyhton360搜索排名查询
关于搜索排名的结果查询,前面有分享过Python百度的搜索排名查询
360搜索排名查询,大同小异,比较烦人的就是协议头的处理
#构建协议头
def ua():
ua=UserAgent()
headers={
'Cookie': 'QiHooGUID=622250714BFE7FEEBC7BE97B1768B7F1.1578470720454; _S=ilmjtet5usmi3a5005tq7of442; opqopq=d8a79fec6212514efe440041e132813c.1578470720',
'Referer': 'https://www.so.com/haosou.html',
"User-Agent":ua.random,
}
return headers
第一个就是ua,还有就是cookies,最后一个就是Referer的添加,这个在图片的反爬中比较常见!
协议头不对的反馈,相信你也会碰到!
三种解析方式的处理,那就在细节上有小差异,同时还有部分数据的处理!
数据处理的关键点:
1.eval()函数
将str转为字典,提取排名
2.排名为空的情况
这里我用异常处理了
re正则的话写了 if else判断处理
3.xpath多个数据获取后的处理
title=''.join(li.xpath('.//a[1]//text()')[:-1]) #标题字符串处理
join函数以及切片的处理
bs4解析
#bs4获取数据
def get_bs4search(keyword,num,cxurl):
jg = []
for i in range(1,int(num)+1):
print(f'正在查询{i}页排名...')
url="https://www.so.com/s?q=%s&pn=%d" % (keyword,i)
req=get_html(url)
soup=BeautifulSoup(req,"html.parser")
lis=soup.find("ul",class_="result").find_all("li",class_="res-list")
print(len(lis))
for li in lis:
title=li.find("a").get_text()
site_url=li.find("a")['href']
try:
pos=eval(li.find("a")['data-res'])['pos'] #eval()函数,将str转为字典,提取排名
pm=(i-1)*10+pos
except:
pm="空"
print(pm,title,site_url)
cxjg=cxwz(keyword, i, pm, title, site_url, cxurl)
if cxjg !=[]:
jg.append(cxjg)
time.sleep(5)
print("排名查询结果:")
print("-----------------------------------------")
if jg == []:
print("该关键词无排名!")
else:
print('n'.join(jg))
print("-----------------------------------------")
print("查询排名结束")
find以及find_all方法
#find方法
#find只能找到符合要求的第一个标签,他返回的是一个对象
soup.find('a')
soup.find('a', class_='xxx')
soup.find('a', title='xxx')
soup.find('a', id='xxx')
soup.find('a', id=re.compile(r'xxx'))
#find_all
#返回一个列表,列表里面是所有的符合要求的对象
soup.find_all('a')
soup.find_all('a', class_='wang')
soup.find_all('a', id=re.compile(r'xxx'))
soup.find_all('a', limit=2) #提取出前两个符合要求的a
当然还有个select方法,这里我没有用,可自行采用了解!
#选择,选择器 css中
常用的选择器
标签选择器、id选择器、类选择器 层级选择器**
div h1 a 后面的是前面的子节点即可
div > h1 > a 后面的必须是前面的直接子节点
属性选择器 input[name='hehe'] select('选择器的') 返回的是一个列表,
列表里面都是对象 find find_all select不仅适用于soup对象,
还适用于其他的子对象,
如果调用子对象的select方法,
那么就是从这个子对象里面去找符合这个选择器的标签。
xpath解析
#xpath获取数据
def get_xmlsearch(keyword,num,cxurl):
jg = []
for i in range(1,int(num)+1):
print(f'正在查询{i}页排名...')
url="https://www.so.com/s?q=%s&pn=%d" % (keyword,i)
req=get_html(url)
html=etree.HTML(req)
lis=html.xpath('//ul[@class="result"]/li[@class="res-list"]')
for li in lis:
title=''.join(li.xpath('.//a[1]//text()')[:-1]) #标题字符串处理
site_url=li.xpath('.//a[1]/@href')[0]
try:
pos=eval(li.xpath('.//a[1]/@data-res')[0])['pos'] #eval()函数,将str转为字典,提取排名
pm=(i-1)*10+pos
except:
pm="空"
print(pm,title,site_url)
cxjg = cxwz(keyword, i, pm, title, site_url, cxurl)
if cxjg != []:
jg.append(cxjg)
time.sleep(5)
print("排名查询结果:")
print("-----------------------------------------")
if jg == []:
print("该关键词无排名!")
else:
print('n'.join(jg))
print("-----------------------------------------")
print("查询排名结束")
re正则解析
#re正则获取数据
def get_research(keyword,num,cxurl):
jg = []
for i in range(1,int(num)+1):
print(f'正在查询{i}页排名...')
url="https://www.so.com/s?q=%s&pn=%d" % (keyword,i)
req=get_html(url)
ul=re.findall(r'<ul class="result">(.+?)<div id="side">',req,re.S)[0]
lis=re.findall(r'<li class="res-list"(.+?)</li>',ul,re.S)
for li in lis:
title=re.findall(r'<a href=".+?>(.+?)</a>',li,re.S)[0]
title=title.replace('<em>','').replace('</em>','') #标题字符串处理
site_url=re.findall(r'<a href="(.+?)".+?>.+?</a>',li,re.S)[0]
if "data-res" in li:
pos=re.findall(r',"pos":(.+?),"m":',li,re.S)[0]
pm = (i - 1) * 10 + int(pos)
else:
pm="空"
print(pm,title,site_url)
cxjg = cxwz(keyword, i, pm, title, site_url, cxurl)
if cxjg != []:
jg.append(cxjg)
time.sleep(5)
print("排名查询结果:")
print("-----------------------------------------")
if jg == []:
print("该关键词无排名!")
else:
print('n'.join(jg))
print("-----------------------------------------")
print("查询排名结束")
运行效果:
测试就找到一个作弊站。。
附完整源码:
#360搜索排名查询
#20200108 by 微信:huguo00289
# -*- coding: utf-8 -*-
import requests,re,time
from fake_useragent import UserAgent
from bs4 import BeautifulSoup
from lxml import etree
#构建协议头
def ua():
ua=UserAgent()
headers={
'Cookie': 'QiHooGUID=622250714BFE7FEEBC7BE97B1768B7F1.1578470720454; _S=ilmjtet5usmi3a5005tq7of442; opqopq=d8a79fec6212514efe440041e132813c.1578470720',
'Referer': 'https://www.so.com/haosou.html',
"User-Agent":ua.random,
}
return headers
#获取访问数据
def get_html(url):
response=requests.get(url,headers=ua(),timeout=10)
print(response.status_code)
req=response.content.decode('utf-8')
return req
#获取搜索结果
#bs4获取数据
def get_bs4search(keyword,num,cxurl):
jg = []
for i in range(1,int(num)+1):
print(f'正在查询{i}页排名...')
url="https://www.so.com/s?q=%s&pn=%d" % (keyword,i)
req=get_html(url)
soup=BeautifulSoup(req,"html.parser")
lis=soup.find("ul",class_="result").find_all("li",class_="res-list")
print(len(lis))
for li in lis:
title=li.find("a").get_text()
site_url=li.find("a")['href']
try:
pos=eval(li.find("a")['data-res'])['pos'] #eval()函数,将str转为字典,提取排名
pm=(i-1)*10+pos
except:
pm="空"
print(pm,title,site_url)
cxjg=cxwz(keyword, i, pm, title, site_url, cxurl)
if cxjg !=[]:
jg.append(cxjg)
time.sleep(5)
print("排名查询结果:")
print("-----------------------------------------")
if jg == []:
print("该关键词无排名!")
else:
print('n'.join(jg))
print("-----------------------------------------")
print("查询排名结束")
#xpath获取数据
def get_xmlsearch(keyword,num,cxurl):
jg = []
for i in range(1,int(num)+1):
print(f'正在查询{i}页排名...')
url="https://www.so.com/s?q=%s&pn=%d" % (keyword,i)
req=get_html(url)
html=etree.HTML(req)
lis=html.xpath('//ul[@class="result"]/li[@class="res-list"]')
for li in lis:
title=''.join(li.xpath('.//a[1]//text()')[:-1]) #标题字符串处理
site_url=li.xpath('.//a[1]/@href')[0]
try:
pos=eval(li.xpath('.//a[1]/@data-res')[0])['pos'] #eval()函数,将str转为字典,提取排名
pm=(i-1)*10+pos
except:
pm="空"
print(pm,title,site_url)
cxjg = cxwz(keyword, i, pm, title, site_url, cxurl)
if cxjg != []:
jg.append(cxjg)
time.sleep(5)
print("排名查询结果:")
print("-----------------------------------------")
if jg == []:
print("该关键词无排名!")
else:
print('n'.join(jg))
print("-----------------------------------------")
print("查询排名结束")
#re正则获取数据
def get_research(keyword,num,cxurl):
jg = []
for i in range(1,int(num)+1):
print(f'正在查询{i}页排名...')
url="https://www.so.com/s?q=%s&pn=%d" % (keyword,i)
req=get_html(url)
ul=re.findall(r'<ul class="result">(.+?)<div id="side">',req,re.S)[0]
lis=re.findall(r'<li class="res-list"(.+?)</li>',ul,re.S)
for li in lis:
title=re.findall(r'<a href=".+?>(.+?)</a>',li,re.S)[0]
title=title.replace('<em>','').replace('</em>','') #标题字符串处理
site_url=re.findall(r'<a href="(.+?)".+?>.+?</a>',li,re.S)[0]
if "data-res" in li:
pos=re.findall(r',"pos":(.+?),"m":',li,re.S)[0]
pm = (i - 1) * 10 + int(pos)
else:
pm="空"
print(pm,title,site_url)
cxjg = cxwz(keyword, i, pm, title, site_url, cxurl)
if cxjg != []:
jg.append(cxjg)
time.sleep(5)
print("排名查询结果:")
print("-----------------------------------------")
if jg == []:
print("该关键词无排名!")
else:
print('n'.join(jg))
print("-----------------------------------------")
print("查询排名结束")
#查询网址是否存在排名
def cxwz(keyword,i,pm,title,site_url,cxurl):
if cxurl in site_url:
cxjg = f'关键词:{keyword},页码:第{i}页,排名:{pm},标题:{title},网址:{site_url}'
print(f'关键词:{keyword},页码:第{i}页,排名:{pm},标题:{title},网址:{site_url}')
else:
cxjg=[]
return cxjg
if __name__=="__main__":
while True:
keyword = input('请输入要查询的关键词:')
num = input('请输入要查询的页码数:')
url = input('请输入要查询的主域名:')
try:
get_bs4search(keyword,num,url)
except IndexError as e:
print(e)
print("查询排名失败!")
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 进程间通信 - 共享内存
- Redis数据淘汰算法
- 无损失放大低分辨率图片
- Linux内存页分配策略
- socket接口层分析
- 数据存储方式——JSON、CSV、MongoDB、Redis、MySQL
- Spring Boot引入swagger-ui 后swagger-ui.html无法访问404
- 多路复用IO内幕
- Linux信号处理
- Shopify主题title/description等SEO设置
- Golang实现守护进程
- LaTeX简单常用方法笔记
- Convolution_model_Application_v1a
- Windows平台快速安装MongoDB和Robo 3T
- Linux内存管理 - slab分配器