#yyds干货盘点# 程序员是这样学习中药学知识的,先用python采集分析一波

少年击剑更吹箫,剑气箫心一例消。这篇文章主要讲述#yyds干货盘点# 程序员是这样学习中药学知识的,先用python采集分析一波相关的知识,希望能为你提供帮助。
本次博客为《爬虫 120 例》第 33 例,重点学习的模块为 pyquery
目标站点分析本次要采集的站点为:http://www.zhongyoo.com/name/page_1.html,其中列表页规则如下:

http://www.zhongyoo.com/name/page_1.html http://www.zhongyoo.com/name/page_2.html http://www.zhongyoo.com/name/page_页码.html

每页有 20 条数据,可查阅总页码为 45 页。
详情页地址可通过标题指向的链接获取。
#yyds干货盘点# 程序员是这样学习中药学知识的,先用python采集分析一波

文章图片

最终的目标数据是获取详情页,各个指标数据,具体如下图所示(不同页面规则有细微差异,解析数据时需要特别注意)
#yyds干货盘点# 程序员是这样学习中药学知识的,先用python采集分析一波

文章图片

本爬虫编写分为两个步骤完成,第一步将所有详情页保存到本地,第二步提取本地 HTML 数据。
编码时间保存 HTML 静态数据到本地,重点注意编码问题即可。
from pyquery import PyQuery as pq import time import requests import chardetdef get_html(page): headers = "User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36"res = requests.get(url=http://www.zhongyoo.com/name/page_.html.format(page), headers=headers, timeout=5)res.encoding = "gb2312"pq_data = https://www.songbingjia.com/android/pq(res.text) titles = pq_data.find("strong> a.title")for item in titles: # 下面两种写法都能获取到 href 属性 # print(pq(item).attr(href)) # print(item.attrib[href]) link = pq(item).attr(href) print(link) save(link) # return len(res.text)def save(link): headers = "User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36"doc = pq(url=link, headers=headers, encoding=gbk) title = doc(title) print(title.text()) if title: title = title.text().split(_)[0]text = doc.html()with open("./html/.html".format(title), "w+") as f: f.write(text.encode("gbk", "ignore").decode("gbk"))if __name__ == __main__: # 静态页面获取代码逻辑 page_data = https://www.songbingjia.com/android/list(range(1, 46)) ret = map(get_html, page_data) for item in ret: print(item)

【#yyds干货盘点# 程序员是这样学习中药学知识的,先用python采集分析一波】在提取网页元素的 href 属性时碰到一个 BUG,如下所示:
AttributeError: HtmlElement object has no attribute attr

此时可以直接使用 ElementTree API 访问标签的属性,也可以对 HtmlElemente 进行封装,即使用 pq 进行包裹,代码如下:
pq(item).attr(href)

还有一种方式是调用上述变量 titles.items 方法,此时就可以通过 .attr 函数,获取 href 属性。
由于网页是 gb2312 编码,实测中发现是 gbk 编码,但在存储文件时,还是存在字符无法被转换,故增加如下代码,去除无法被转换的字符。
with open("./html/.html".format(title), "w+") as f: f.write(text.encode("gbk", "ignore").decode("gbk"))

注意以下问题,都是字符编码的问题。
> gb2312 codec cant encode character \\u85a2 in position 14654: illegal multibyte sequence > gbk codec cant encode character \\xa9 in position 20633: illegal multibyte sequence > utf-8 codec cant decode byte 0xb2 in position 164: invalid start byte

编写数据提取部分代码时,发现使用 pyquery 提取会变得很复杂,还是需要正则表达式的介入,以下代码可供参考。
def extract_data(): file_names = os.listdir("./html/") for file in file_names: with open(f"./html/file", "r") as f: html_content = f.read() # 解析数据 pq_obj = pq(html_content) items = pq_obj.find(div.text p) print("获取到的段落数为,", len(items)) # 等待提取的字符串 item_str = "" for item in items: text = pq(item).text() item_str += text # 使用正则提取数据 # 正名/中药名/药名 name_p = re.compile(【(正名|中药名|药名)】([\\s\\S]*?)【) name = name_p.findall(item_str) # 别名 alias_p = re.compile(【别名】([\\s\\S]*?)【) alias = alias_p.findall(item_str) # 英文名 en_name_p = re.compile(【英文名】([\\s\\S]*?)【) en_name = en_name_p.findall(item_str) print(name, alias, en_name)

#yyds干货盘点# 程序员是这样学习中药学知识的,先用python采集分析一波

文章图片

收藏时间

    推荐阅读