① python网页解析库:用requests-html爬取网页
Python 中可以进行网页解析的库有很多,常见的有 BeautifulSoup 和 lxml 等。在网上玩爬虫的文章通常都是介绍 BeautifulSoup 这个库,我平常也是常用这个库,最近用 Xpath 用得比较多,使用 BeautifulSoup 就不大习惯,很久之前就知道 Reitz 大神出了一个叫 Requests-HTML 的库,一直没有兴趣看,这回可算歹着机会用一下了。
使用 pip install requests-html 安装,上手和 Reitz 的其他库一样,轻松简单:
这个库是在 requests 库上实现的,r 得到的结果是 Response 对象下面的一个子类,多个一个 html 的属性。所以 requests 库的响应对象可以进行什么操作,这个 r 也都可以。如果需要解析网页,直接获取响应对象的 html 属性:
不得不膜拜 Reitz 大神太会组装技术了。实际上 HTMLSession 是继承自 requests.Session 这个核心类,然后将 requests.Session 类里的 requests 方法改写,返回自己的一个 HTMLResponse 对象,这个类又是继承自 requests.Response,只是多加了一个 _from_response 的方法来构造实例:
之后在 HTMLResponse 里定义属性方法 html,就可以通过 html 属性访问了,实现也就是组装 PyQuery 来干。核心的解析类也大多是使用 PyQuery 和 lxml 来做解析,简化了名称,挺讨巧的。
元素定位可以选择两种方式:
方法名非常简单,符合 Python 优雅的风格,这里不妨对这两种方式简单的说明:
定位到元素以后势必要获取元素里面的内容和属性相关数据,获取文本:
获取元素的属性:
还可以通过模式来匹配对应的内容:
这个功能看起来比较鸡肋,可以深入研究优化一下,说不定能在 github 上混个提交。
除了一些基础操作,这个库还提供了一些人性化的操作。比如一键获取网页的所有超链接,这对于整站爬虫应该是个福音,URL 管理比较方便:
内容页面通常都是分页的,一次抓取不了太多,这个库可以获取分页信息:
结果如下:
通过迭代器实现了智能发现分页,这个迭代器里面会用一个叫 _next 的方法,贴一段源码感受下:
通过查找 a 标签里面是否含有指定的文本来判断是不是有下一页,通常我们的下一页都会通过 下一页 或者 加载更多 来引导,他就是利用这个标志来进行判断。默认的以列表形式存在全局: ['next','more','older'] 。我个人认为这种方式非常不灵活,几乎没有扩展性。 感兴趣的可以往 github 上提交代码优化。
也许是考虑到了现在 js 的一些异步加载,这个库支持 js 运行时,官方说明如下:
使用非常简单,直接调用以下方法:
第一次使用的时候会下载 Chromium,不过国内你懂的,自己想办法去下吧,就不要等它自己下载了。render 函数可以使用 js 脚本来操作页面,滚动操作单独做了参数。这对于上拉加载等新式页面是非常友好的。
② python爬虫时,bs4无法读取网页标签中的文本
稍微说一下背景,当时我想研究蛋白质与小分子的复合物在空间三维结构上的一些规律,首先得有数据啊,数据从哪里来?就是从一个涵盖所有已经解析三维结构的蛋白质-小分子复合物的数据库里面下载。这时候,手动一个个去下显然是不可取的,我们需要写个脚本,能从特定的网站选择性得批量下载需要的信息。python是不错的选择。
import urllib #python中用于获取网站的模块
import urllib2, cookielib
有些网站访问时需要cookie的,python处理cookie代码如下:
cj = ***.cookiejar ( )
opener = ***.build_opener( ***.httpcookieprocessor(cj) )
***.install_opener (opener)
通常我们需要在网站中搜索得到我们需要的信息,这里分为二种情况:
1. 第一种,直接改变网址就可以得到你想要搜索的页面:
def GetWebPage( x ): #我们定义一个获取页面的函数,x 是用于呈递你在页面中搜索的内容的参数
url = 'http://xxxxx/***.cgi?&' + ‘你想要搜索的参数’ # 结合自己页面情况适当修改
page = ***.urlopen(url)
pageContent = ***.read( )
return pageContent #返回的是HTML格式的页面信息
2.第二种,你需要用到post方法,将你搜索的内容放在postdata里面,然后返回你需要的页面
def GetWebPage( x ): #我们定义一个获取页面的函数,x 是用于呈递你在页面中搜索的内容的参数
url = 'http://xxxxx/xxx' #这个网址是你进入搜索界面的网址
postData = ***.urlencode( { 各种‘post’参数输入 } ) #这里面的post参数输入需要自己去查
req= ***.request (url, postData)
pageContent = ***.urlopen (req). read( )
return pageContent #返回的是HTML格式的页面信息
在获取了我们需要的网页信息之后,我们需要从获得的网页中进一步获取我们需要的信息,这里我推荐使用 BeautifulSoup 这个模块, python自带的没有,可以自行网络谷歌下载安装。 BeautifulSoup 翻译就是‘美味的汤’,你需要做的是从一锅汤里面找到你喜欢吃的东西。
import re # 正则表达式,用于匹配字符
from bs4 import BeautifulSoup # 导入BeautifulSoup 模块
soup = BeautifulSoup(pageContent) #pageContent就是上面我们搜索得到的页面
soup就是 HTML 中所有的标签(tag)BeautifulSoup处理格式化后的字符串,一个标准的tag形式为:
hwkobe24
通过一些过滤方法,我们可以从soup中获取我们需要的信息:
(1) find_all ( name , attrs , recursive , text , **kwargs)
这里面,我们通过添加对标签的约束来获取需要的标签列表, 比如 ***.find_all ('p') 就是寻找名字为‘p’的 标签,而***.find_all (class = "tittle") 就是找到所有class属性为"tittle" 的标签,以及***.find_all ( class = ***.compile('lass')) 表示 class属性中包含‘lass’的所有标签,这里用到了正则表达式(可以自己学习一下,非常有用滴)
当我们获取了所有想要标签的列表之后,遍历这个列表,再获取标签中你需要的内容,通常我们需要标签中的文字部分,也就是网页中显示出来的文字,代码如下:
tagList = ***.find_all (class="tittle") #如果标签比较复杂,可以用多个过滤条件使过滤更加严格
for tag in tagList:
print ***.text
***.write ( str(***.text) ) #将这些信息写入本地文件中以后使用
(2)find( name , attrs , recursive , text , **kwargs )
它与 find_all( ) 方法唯一的区别是 find_all() 方法的返回结果是值包含一个元素的列表,而 find() 方法直接返回结果
(3)find_parents( ) find_parent( )
find_all() 和 find() 只搜索当前节点的所有子节点,孙子节点等. find_parents() 和 find_parent() 用来搜索当前节点的父辈节点,搜索方法与普通tag的搜索方法相同,搜索文档搜索文档包含的内容
(4)find_next_siblings() find_next_sibling()
这2个方法通过 .next_siblings 属性对当 tag 的所有后面解析的兄弟 tag 节点进代, find_next_siblings() 方法返回所有符合条件的后面的兄弟节点,find_next_sibling() 只返回符合条件的后面的第一个tag节点
(5)find_previous_siblings() find_previous_sibling()
这2个方法通过 .previous_siblings 属性对当前 tag 的前面解析的兄弟 tag 节点进行迭代, find_previous_siblings()方法返回所有符合条件的前面的兄弟节点, find_previous_sibling() 方法返回第一个符合条件的前面的兄弟节点
(6)find_all_next() find_next()
这2个方法通过 .next_elements 属性对当前 tag 的之后的 tag 和字符串进行迭代, find_all_next() 方法返回所有符合条件的节点, find_next() 方法返回第一个符合条件的节点
(7)find_all_previous() 和 find_previous()
这2个方法通过 .previous_elements 属性对当前节点前面的 tag 和字符串进行迭代, find_all_previous() 方法返回所有符合条件的节点, find_previous()方法返回第一个符合条件的节点
具体的使用方法还有很多,用到这里你应该可以解决大部分问题了,如果要更深入了解可以参考官方的使用说明哈!
③ 用python爬取关键词并解释
Copyright © 1999-2020, CSDN.NET, All Rights Reserved
python
打开APP
小羊努力搞代码
关注
学习日志:Python 实现网络爬虫——提取关键字 原创
2022-06-19 13:02:38
小羊努力搞代码
码龄174天
关注
编写一段Python代码,向网络提交查询关键词“桃花源记”,抓取网络的查询结果,要求有文字、链接,可以在浏览器中打开抓取的链接,或者调用浏览器打开抓取的链接。
红框内是根据网站信息需要更改的内容。.png
附上完整代码:
import json
import requests
from lxml import etree
headers = {
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/88.0.4324.104 Safari/537.36"
}
response = requests.get('https://www..com/s?wd=桃花源记&lm=0', headers=headers)
r = response.text
html = etree.HTML(r, etree.HTMLParser())
r1 = html.xpath('//h3')
r2 = html.xpath('//*[@class="content-right_8Zs40"]')
r3 = html.xpath('//*[@class="c-row source_1Vdff OP_LOG_LINK c-gap-top-xsmall"]/a/@href')
for i in range(4):
r11 = r1[i].xpath('string(.)')
r22 = r2[i].xpath('string(.)')
r33 = r3[i]
with open('桃花源记.txt', 'a', encoding='utf-8') as c:
c.write(json.mps(r11,ensure_ascii=False) + '\n')
c.write(json.mps(r22, ensure_ascii=False) + '\n')
c.write(json.mps(r33, ensure_ascii=False) + '\n')
print(r11, end='\n')
print('------------------------')
print(r22, end='\n')
print(r33)
④ python中如何通过关键字查找到指定的HTML标签
可以使用正则表达式的方法
正则表达式:工作职责:</th>s+<td>(.+?)</td>
importre
content="页面内容"
re_1=re.search('工作职责:</th>s+<td>(.+?)</td>',content)
ifre_1:
printre_1.group(1)
else:
print"notfind!"
因为正则表达式有中文 所以要保证你的内容与文本是一个编码
⑤ 如何用产品id索引爬取标签内的产品各项标题链接价格 python
产品id索引爬取标签内的产品各项标题链接价格 python可以使用网页请求方式:最常见的方式,一般用于获取或者查询资源信息,也是大多数网站使用的方式,响应速度快,或者多以表单形式上传参数,因此除了查询信息外,还可以修改信息。
另外可以以开发者的身份进入网站进行价格查询,打开网页,用开发者模式,任意复制一条首条新闻标题,粘贴到搜索框里。开发者模式,依次点击‘network’,‘XHR’找到翻译数据,点击Headers,请求为get方式,使用Beautiful soup解析网页,然后再安装bs。
Beautiful soup 指定xlml解析器进行解析,soup=BeautifulSoup(strhtml.text,'lxml'使用select(选择器)定位数据,使用浏览器的开发者模式,将鼠标停留在对应数据位置并右击。
开发者界面会有被选中部分,右击 ---> selector; 将路径粘贴在文档中,代码如下#main > div > div.mtop.firstMod.clearfix > div.centerBox > ul.newsList > li:nth-child(1) > a。
这是选中的第一条路径,但我们要获取所有的新闻头条,因此将:li:nth-child(1)中冒号(包含冒号)后面的删掉。如下:#main > div > div.mtop.firstMod.clearfix > div.centerBox > ul.newsList > li > a,然后就可以直接查询了。
⑥ python3 用BeautifulSoup 爬取指定ul下的a标签
用select('ul的css路径').find_all(...)
css路径直接用浏览器开发视图,从ul复制就好,当然也可以把前面多余的部分删掉
⑦ 如何用python 写一个爬虫用来爬P 站特定标签下的高赞作品
Python写这些爬虫,批量获取还是挺简单的……不长逛P站但是写了个可以获取知乎指定收藏夹下的高赞答案的东西……
获取知乎指定收藏夹下的高赞答案
获取P站特定标签下的高赞作品
这两个需求应该是差不多的……
爬取收藏夹的代码大概是这样:
__author__ = '7sDream'
import hu
collection = hu.Collection('')
for answer in collection.answers:
if answer.upvote >= 1000:
answer.save(path=collection.name)
结果是这样:
理论上来说爬P站应该差不多……
做好cookies管理,HTML解析就差不多了。
如果Python会的差不多了看看这个知乎模块的源码应该能写出来P站的
⑧ Python爬虫怎么循环截取html标签中间的内容
如果是中间的数据直接就用bs4最简单
from bs4 import BeautifulSoup
#这里是请求过来的额数据处理,提取标签
html = BeautifulSoup(response.text, 'html.parser')
body = html.body # 获取body部分数据
div = body.find("div",{'id','today'}) #用find去找div标签,id叫 today的标签里面的数据
就可以了
如果要提取标签内容比如value的值
div = body.find("input",id='hidden_title')['value']
⑨ python爬虫,用find_all()找到某一标签后,怎么获取下面数个同名子标签的内容
#!/usr/bin/envpython
#coding:utf-8
frombs4importBeautifulSoup
#这个data可以替换成你的div=soup.find_all('div',class_="star")
#取的时候记得循环处理
data='''
<div>
<spanclass='a'protype='d'>1</span>
<spanclass='a'protype='d'>2</span>
<spanclass='a'protype='d'>3</span>
<spanclass='a'protype='d'>4</span>
</div>
'''
soup=BeautifulSoup(data,'lxml')
spans=soup.find_all('span')
span_content=[]
foriinspans:
printi,i.text#这里取标签span的内容
span_content.append(i.text)
printspan_content
------------------------
<spanclass="a"protype="d">1</span>1
<spanclass="a"protype="d">2</span>2
<spanclass="a"protype="d">3</span>3
<spanclass="a"protype="d">4</span>4
[u'1',u'2',u'3',u'4']
⑩ 如何用Python爬取出HTML指定标签内的文本
你好!
可以通过lxml来获取指定标签的内容。
#安装lxml
pipinstalllxml
importrequests
fromlxmlimporthtml
defgetHTMLText(url):
....
etree=html.etree
root=etree.HTML(getHTMLText(url))
#这里得到一个表格内tr的集合
trArr=root.xpath("//div[@class='news-text']/table/tbody/tr");
#循环显示tr里面的内容
fortrintrArr:
rank=tr.xpath("./td[1]/text()")[0]
name=tr.xpath("./td[2]/div/text()")[0]
prov=tr.xpath("./td[3]/text()")[0]
strLen=22-len(name.encode('GBK'))+len(name)
print('排名:{:<3},学校名称:{:<{}} ,省份:{}'.format(rank,name,strLen,prov))
希望对你有帮助!