这是第一次用requests, beautifulsoup实现爬虫,此次爬取的是一个股票信息网站:http://www.gupiaozhishi.net.cn。
实现非常简单,只是为了demo使用的数据采集,故而基本未做任何的优化,比方说代理,并发等。但对网上较为复杂的爬虫实例而言,此节可以作为简单的入门实例参考。
基本上爬虫的第一步都是对网页的解析,http://www.gupiaozhishi.net.cn这个网站非常简单,基本要爬取的信息的url信息均在首页上可以爬取到。
1 2 3 4 5 6 7 8 | import requests home = requests.get('http://www.gupiaozhishi.net.cn/',headers = {},cookies = {}) home.encoding = 'gb2312' from bs4 import BeautifulSoup home_html_doc = home.text home_soup = BeautifulSoup(home_html_doc, 'lxml') |
通过上面的代码就已经将网页信息的html信息爬取下来,网站的默认的编码通过<meta>中的charset属性查看,由于charset = 'gb2312' ,故这边使用'gb2312'的编码方式。
将爬取下来的html信息传入BeautifulSoup实例,以'lxml'的方式对html信息进行解析。实际练习过程中,可以使用print( home_soup.prettify())的方式,将requests获取的http文件解析成我们习惯看的html格式的内容。
由于我此次是希望通过爬取首页信息获取所有的FAQ问题的url,所以通过下面代码获取相应的url信息。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | url_list = [] # 用于存储所有的a 标签中的href内容 knowledge_url_list = home_soup.find_all('a') # 抓取到网页的所有a标签的信息,存储类型为list。 for i in knowledge_url_list: uri = i.get('href') # 找到所有a标签内的 超链接信息 url_list.append(uri) '''虽然上面已经解析出了所有的href信息,但是有很多信息并不是我们想要的,发现想要的FAQ信息的url都均有共同的特性,以.html结尾。所以选择用正则的方式剔除到不要的''' pattern_url_list =[] #用正则表达式的方式挑选符合条件的href内容 import re for i in url_list: patterns =r'[a-zA-Z]+://[^\s]*.html$' res = re.match(patterns , i) if res is not None: pattern_url_list.append(res.group()) #最后获取符合条件的url共计242个,即242个FAQ |
成功爬取所有的信息后,我们就可以用各种方式去实现抓取所有的url信息里面的相应内容,针对一个FAQ页面的问题进行了解析处理,加上测试发现基本所有的url都可以用同样的方式去处理。特殊页面特殊处理。
其中发现了几个问题:
1. 字符编码问题:网页的问题中有少量的繁体字,不在gb2312的字符范围内,无法解析,出现乱码;
2. 有大量的内容信息中打印出来的信息有 注释内容,需要将注释内容剔除。
3. 文本内容在一个span标签内,通过<br/>标签实现换行,少量的<p>标签的内容在内部最后。
4. 实现过程中采用的是将文本内容用列表的方式添加,在for循环体内,list类型的可变属性导致出现数据叠加。
下面的实现代码中实现了上面提到的几个问题,解决方法均有注释:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | from bs4 import CData from bs4 import element import json import os pattern_url_list.remove('http://www.gupiaozhishi.net.cn/stock/chaogu/200702/4958.html') pattern_url_list.remove('http://www.gupiaozhishi.net.cn/stock/rumen/200702/94.html') #以上两个url是在实际测试中发现有特殊问题的两个url,选择直接剔除,避免复杂度。 question_dicts = {} contents_list_str = [] #定义函数每次获取url中的问题和答案。 for u in pattern_url_list: question = requests.get(u, headers = {}, cookies = {}) question.encoding = 'gb18030' #由于繁体在gb18030中一定有映射关系,尝试后发现中文繁体乱码现象果然解决。 question_html_doc = question.text question_soup = BeautifulSoup(question_html_doc,'lxml') [s.extract() for s in question_soup(['br','p'])] #去除不想要的br,p标签 question_soup.prettify() #测试过程中用来打印查看 question_name = question_soup.meta['content'] #获取标题 question_content = question_soup.find_all('span')[0] contents_list = question_soup.find_all('span')[0].contents '''每个问题页面上有三个span标签,其中每个页面上的第一个span标签内存储存了所有的答案的文本内容。''' for i in contents_list: if type(i) == element.Comment: pass #如果这一行内容是注释,清除 else: if len(i) <1 or i is None: pass else: i = i.strip() # 剔除空行和多余的空格键,换行符等 contents_list_str.append(str(i)) #将符合条件的字符串行添加到答案内容列表中 contents = ''.join(contents_list_str) #将列表内字符串拼接为一个字符串 question_dicts[question_name] = contents #将标签和内容添加到字典中 contents_list_str = [] #在下一次循环前,清空列表。防止元素叠加 |
最后将返回的字典内容写到文件中,目前采用的是json格式的:
1 2 3 | # 将返回的内容写到文件 with open(os.path.dirname(__file__)+'/ff.json','w') as fp: json.dump(question_dicts,fp) |
如果要读取:
1 2 3 4 5 | import json f=open('ff.json','r',encoding='utf8') data=json.loads(f.read()) print(data) f.close() |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 智能桌面机器人:用.NET IoT库控制舵机并多方法播放表情
· Linux glibc自带哈希表的用例及性能测试
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 手把手教你在本地部署DeepSeek R1,搭建web-ui ,建议收藏!
· 新年开篇:在本地部署DeepSeek大模型实现联网增强的AI应用
· Janus Pro:DeepSeek 开源革新,多模态 AI 的未来
· 互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(三):用.NET IoT库
· 【非技术】说说2024年我都干了些啥