课程:https://www.icourse163.org/learn/BIT-1001870001
Requests库:
r=requests.get(url)
向服务器发送请求资源的Request对象,返回一个包含服务器资源的Response对象。
get()方法包括其他控制参数,在此不展开r.encoding
为从HTTP header中猜测的响应内容编码方式 ,r.apparent_encoding
为具体分析得出的编码方式。一般使r.encoding=r.apparent_encoding.
r.raise_for_status()
若不为200,则为访问异常。
HTTP协议方法与Requests库中对应方法:
待补充
爬取静态网页常用框架:
try:
r=requests.get(url)
r.encoding=r.apparent_encoding
return r.text
except:
return "ERROR!"
Beautiful Soup库:
通过Beautiful Soup库解析、遍历标签树获取信息。
当soup=BeautifulSoup(r.text,"html.parser")
soup.<tag>
返回HTML文档中的标签(若存在多个则返回第一个)soup.<tag>.name
得到标签的名字
BeautifulSoup通过标签间下行遍历、上行遍历和平行遍历得到目标信息:
- 下行遍历:
for child in soup.body.children:
print(child)
-
上行遍历
-
平行遍历
注意:在同一父节点下的平行结点才可进行平行遍历
soup.find_all()方法:
原型:find_all(name, attrs, recursive, string , **kwargs)
name
参数:对标签名称的检索字符串。
soup.find_all('a')
:返回一个列表,存储所有<a></a>
标签及其内部内容
soup.find_all(['a','b'])
:存储所有<a></a>
,<b></b>
标签及其内部内容attrs
参数:对标签属性值的检索字符串,如class、id等。recursive
参数:是否对子孙全部检索,默认为true。string
参数:<>…</>中字符串区域的检索字符串。
其他find方法
爬取网页示例:世界大学排名
原网页:http://rankings.betteredu.net/qs/world-university-rankings/latest/2022.html
import bs4.element
import requests
from bs4 import BeautifulSoup
import bs4
def getHTMLText(url):
try:
r=requests.get(url,timeout=30)
r.encoding=r.apparent_encoding
return r.text
except:
return ""
def fillUnivList(ulist,html):
soup=BeautifulSoup(html,"html.parser")
for tr in soup.find('tbody').children:#遍历tbody标签内所有孩子结点中的tr标签
if isinstance(tr,bs4.element.Tag):#避免tbody的字符串孩子结点被存入列表
tds=tr('td')
ulist.append([tds[0].string, tds[1].string, tds[2].string])
def printUnivList(ulist,num):
print("{:^10}\t{:<30}\t{:^10}".format("排名", "大学", "地区"))
for i in range(num):
u=ulist[i]
print("{:^10}\t{:<30}\t{:^10}".format(u[0], u[1], u[2]))
print("Suc")
def main():
uinfo=[]
url="http://rankings.betteredu.net/qs/world-university-rankings/latest/2022.html"
html=getHTMLText(url)
fillUnivList(uinfo,html)
printUnivList(uinfo,20)
main()
结果如图:
对B站【关键词】视频按新发布顺序的爬取:
import requests
import re
def getHTMLText(url):
try:
r=requests.get(url,timeout=30)
#r.encoding=r.apparent_encoding 直接使用apparent_encoding可能导致乱码。应当优先确认header中是否指定了编码方式,若是,则不使用此语句。
return r.text
except:
return ""
def fillList(uinfo,html):
try:
#根据网页源代码,确定查找的正则表达式
tlt=re.findall(r'a title\=\".*?\"',html)#搜索格式为 a title="标题" 的内容
ult = re.findall(r'\"author\"\:\".*?\"', html)
plt=re.findall(r'\"play\"\:[\d]*', html)
for i in range(len(tlt)):
#取等号后的内容并去引号
title=tlt[i].split('=')[1]
title = eval(title)
#去引号并取冒号后的内容
upname = eval(ult[i].split(':')[1])
play = eval(plt[i].split(':')[1])
uinfo.append([title, upname, play])
except:
return " "
def printList(uinfo):
#tplt = "{:^4}\t{:^70}\t{:^10}\t{:^10}"
#print(tplt.format("序号", "标题", "UP名", "播放量", chr(12288)))
#chr(12288)按中文空格填充,但中英混合情况似乎同样排版混乱,待解决
count = 0
for g in uinfo:
count = count + 1
print("编号:%d\t\t标题:%s\t\tUP主:%s\t\t播放:%s" %(count, g[0], g[1], g[2]))
#print(tplt.format(count, g[0], g[1], g[2], chr(12288)))
def main():
uinfo=[]
key='奥运会'
link='https://search.bilibili.com/all?keyword='+key+'&order=pubdate&page='
depth=3#前3页内容
for i in range (depth):
j=i+1
url=link+str(j)
html=getHTMLText(url)
fillList(uinfo,html)
printList(uinfo)
main()
补充:re.compile()的参数re.S
requests库对超链接中内容的爬取,以电影天堂为例:
url="https://www.dytt8.net/"
child_url_list=[]
resp=requests.get(url)
resp.encoding=resp.apparent_encoding
obj1 = re.compile(r"<a href=.*?>最新电影下载.*?<a href='(?P<URL>.*?)'>",re.S)#pattern类
obj2 = re.compile(r"<br />◎译 名(?P<tr_name>.*?)<br />◎片 名(?P<name>.*?)<br />.*?"
r"<a target=.*?href=(?P<link>.*?)>", re.S)
#获取超链接
result=obj1.finditer(resp.text)
for it in result:
list=it.group('URL')
child_url=url+list.strip("/")
child_url_list.append(child_url)
#依次进入超链接并得到内容:译名、片名与磁力链接
for href in child_url_list:
resp_child = requests.get(href)
resp_child.encoding = 'gb2312'
INFO=obj2.search(resp_child.text)
print(INFO.group("name"))
print(INFO.group("tr_name"))
magnet=INFO.group("link")
magnet=eval(magnet)#去引号
print(magnet)
print("\n")
结果如图(漢字问题未解决):
获取Pixiv日榜图片:
https://blog.youkuaiyun.com/MZM9161/article/details/119655060