以下是本人基于上课所学的的内容浓缩而成的一篇代码。
主要介绍了get网页请求,BeautifulSoup网页解析,Xpath网页解析。
正则表达式网页解析在下一篇文章中解释。
2021/12/8首发于csdn,有错误和不足欢迎指出。
----更新记录----
2021/12/11将正则表达式部分移入下一篇文章,修正了最后一行代码缩进,增加了对BeautifulSoup的.string方法的解释。
''' http协议使用了请求/响应模型,爬虫作为客户端模拟发起请求,服务器做出响应 连接web服务器,爬虫发送http请求,服务器接收请求并返回htttp响应,释放TCP连接,爬虫解析HTML内容 正是因为连接会被关闭,所以需要使用cookie(以键值对形式保存)对用户历史 *** 作(如表单密码的提交)进行记录 ''' import requests # requests请求库 import chardet # 字符串/文件编码检测模块 from bs4 import BeautifulSoup # bs4解析网页 from lxml import etree # Xpath解析网页 # 基本参数 url = "http://www.tipdm.com/" # 请求头header = user-agent headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.55 Safari/537.36 Edg/96.0.1054.41"} timeout1 = 2 # 设置超时时间为2s,超时后会报错,程序自动停止 timeout2 = 0.001 # 超时时间过短会直接报错 '''get请求''' # 发送请求用encoding rqg = requests.get(url, headers=headers, timeout=timeout1) print("结果类型:", type(rqg)) # 查看结果类型 print("状态码:", rqg.status_code) # 查看状态码 # 当requests库解析编码错误时,用chardet库指定编码 print("编码:", rqg.encoding) # 查看编码 print("detect方法检测结果:", chardet.detect(rqg.content)) # 头部里面有个charset=utf-8 rqg.encoding = chardet.detect(rqg.content)['encoding'] # 将检测到的编码赋值给rqg.encoding print("改变后的编码:", rqg.encoding) # 查看改变后的编码 print("响应头:", rqg.headers) # 查看响应头 # print("网页内容:", rqg.text) # 查看网页内容 # 初始化html,先获取html再做解析 # 获取网页用decode html = rqg.content.decode("utf-8") # 内容上与rqg.text一致 '''BeautifulSoup解析网页''' # 生成BeautifulSoup对象,使用"lxml"解析器或用"html.parser"解析器 # 这个对象内并没有真正的html/xml的tag,但是可以当做tag使用 soup = BeautifulSoup(html, "lxml") # BeautifulSoup对象 # soup = BeautifulSoup(open("index.html", encoding = "utf-8"), "html.parser") # 解析本地网页 # print("输出格式化的BeautifulSoup对象:", soup.prettify()) # 只保存了关键的标记与内容,而且去除了注释(comment对象) tag = soup.ul # 找到html中第一个ul标签块里包含的内容,找所有ul用find_all # print("查看第一个u标签块l包含的内容", tag) print("tag第一个标签的名字(其实已经知道是ul了):", tag.name) print("tag第一个标签的属性及取值:", tag.attrs) # 属性是键值对显示,tag.attrs["id"]可以只看id的值,引号不可以去掉 print("tag里第一个li标签块的内容:", tag.li) # print("tag里所有文字部分的内容:", tag.text) # print("使用get_text()获取所有文字的文本内容:", tag.get_text()) print("tag里第一个li的文字内容:", tag.li.text) # NavigableString对象即包含在标签块内的文字 # 可以用.string(这样会获得NavigableString对象,且被注释的文本会被显示,但不知道它原来是注释) # .text/.get_text方式获取(这样获得的是str) # NavigableString对象无法被编辑,但可以用replace_with方法替换 print("tag里第一个li的文字内容:", tag.li.string) print("tag.text,tag.li.get_text()和tag.string对象类型:", type(tag.li.text), type(tag.li.get_text()), type(tag.li.string)) # find_all与find方法 print("查找第一个ul块:", soup.find("ul")) print("查找所有的class='menu'的ul块,结果为一个列表,如果找不到就为空列表。 注意写法是class_,不是class,id还是原来那样写:", soup.find_all("ul", class_='menu')) # Find_all得到是列表,可以切片方式得到元素 s1 = soup.find_all('ul') print("切片结果:", s1[0:2]) # 结果是前两个ul标签块里面的内容 # 存储获取的文本与链接 # urls = [] # text = [] # for tag in soup.ul.find_all("a"): # urls.append(tag.get("herf")) # text.append(tag.get_text()) for t in soup.ul.find_all("a"): print(t.get_text(), t.get("herf"), end="n") '''Xpath解析网页''' # 生成Xpath对象,parser是解析器 # Xpth可以自动修正html文本,例如自动闭合未闭合的标签 xp = etree.HTML(html, parser=etree.HTMLParser(encoding='utf-8')) # tostring方法可以输出修正后的html代码,也可以直接读取文本进行解析,但结果为bytes类型,需要decode转str输出 # result = etree.tostring(html, encoding='utf-8', pretty_print=True, method="html") # print(result.decode('utf-8')) # Xpath用类似正则的方式来匹配HTML中的内容 print("所有的a标记,不管在什么位置", xp.xpath("//a")) print("body/div里的第一个a结点", xp.xpath("body/div/a[1]")) print("body/div里的最后一个a结点", xp.xpath("body/div/a[last()]")) print("body/div里的倒数第二个a结点", xp.xpath("body/div/a[last()-1]")) print("body/div里的前两个a结点", xp.xpath("body/div/a[position()<3]")) # print("body里所有div里的xx元素值大于10的结点", xp.xpath("body/div[xx>10.00])) print("body里所有class属性值为container clearfix的div结点", xp.xpath("body/div[@class='container clearfix']")) print("body里所有div下所有的内容:", xp.xpath("body/div/*")) print("body里所有带有属性的前两个div结点", xp.xpath("body/div[@* and position()<3]")) print("body里所有id值以co开头的div结点", xp.xpath("body/div[starts-with(@id,'co')")) # contanins已经是无效谓词了 # print("body里所有id值含co和en的div结点", xp.xpath("body/div[contanins(@id,'co')]")) print("head里所有的title的文本内容:", xp.xpath("head/title/text()")) r2 = xp.xpath("//p[starts-with(@class,'p1')]") #查找所有以“p1”开始的class属性的p for j in r2: # 查看该结点下所有的文本 t2 = j.xpath('string(.)') print(t2)
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)