程序员是这样学习中药学知识的,先用python采集分析一波
Posted 梦想橡皮擦
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了程序员是这样学习中药学知识的,先用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 页。
详情页地址可通过标题指向的链接获取。
最终的目标数据是获取详情页,各个指标数据,具体如下图所示(不同页面规则有细微差异,解析数据时需要特别注意)
本爬虫编写分为两个步骤完成,第一步将所有详情页保存到本地,第二步提取本地 HTML 数据。
编码时间
保存 HTML 静态数据到本地,重点注意编码问题即可。
from pyquery import PyQuery as pq
import time
import requests
import chardet
def 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 = 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 = list(range(1, 46))
ret = map(get_html, page_data)
for item in ret:
print(item)
在提取网页元素的 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 can't encode character '\\u85a2' in position 14654: illegal multibyte sequence
> 'gbk' codec can't encode character '\\xa9' in position 20633: illegal multibyte sequence
> 'utf-8' codec can't 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)
如果你看到这里,那么一个新的案例又实现啦。
收藏时间
代码仓库地址:https://codechina.csdn.net/hihell/python120,去给个关注或者 Star 吧。
今天是持续写作的第 220 / 365 天。
可以关注,点赞、评论、收藏。
更多精彩
以上是关于程序员是这样学习中药学知识的,先用python采集分析一波的主要内容,如果未能解决你的问题,请参考以下文章
程序员真人秀又来了!呼兰当主持挑灯狂补知识,SSS大佬本科竟是药学,清华朱军张敏等加入导师团...
《深入浅出Python》与《Python网络数据采集》读后感