for u in urls: response = requests.get(u).text response = response.replace('<br />', '</p><p>') soup = BeautifulSoup(response, "html.parser", from_encoding="utf-8") name = soup.find_all("h1")[0].text.strip() print(name) origin_come = [] famous_person = [] live_area = [] save = None p_list = soup.find_all("p") for p in p_list: t = p.text.strip() if t == '历史来源': save = origin_come continue elif t == '家族名人': save = famous_person continue elif t == '地望分布'or t == '迁徙分布': save = live_area continue if save isnotNoneand t != '': save.append(p.text.strip()) tmp = { 'origin_come': origin_come, 'famous_person': famous_person, 'live_area': live_area, } name_info[name].append(tmp)
doc = docx.Document() for name, info in name_info.items(): doc.add_heading(name, 0) data = info[0] doc.add_heading('来源出处', 1) origin_come = data['origin_come'] for i in range(len(origin_come)): doc.add_paragraph(origin_come[i])
doc.add_heading('历史名人', 1) famous_person = data['famous_person'] for i in range(len(famous_person)): doc.add_paragraph(famous_person[i])
doc.add_heading('地望分布', 1) live_area = data['live_area'] for i in range(len(live_area)): doc.add_paragraph(live_area[i])
doc.save('./test.docx')
这里面有几个地方需要解释一下:
规范网页结构
在爬取的过程中,我发现有的网页代码挺混乱的,比如下面:
正常的:
不正常的:
王 字的 历史名人 就没在 p 标签内,所以,我们原来的代码运行就解析不出来。
因为,解析不出单个的 历史名人 ,而是 *****,历史名人(历史名人在一句话中)。
这种是内容不在 p 中,但是,仔细观察,前面都有一个
<br>
所以,我们才有了下面的代码
response = response.replace('<br />', '</p><p>')
让所有的内容都放在 p 标签内。
一个编程技巧
我在想,一个姓需要搜集三个信息,那么,怎么才能合理的添加到不同的数组中,后来,我使用了指针
for p in p_list:
t = p.text.strip()
if t == '历史来源':
save = origin_come
continue
elif t == '家族名人':
save = famous_person
continue
elif t == '地望分布' or t == '迁徙分布':
save = live_area
continue
if save is not None and t != '':
save.append(p.text.strip())