网络爬虫包括了四大部分:url管理器,url下载器,url解析器,url输出器。最后由主程序调用者四个部分
首先来看 url管理器:主要功能是将未解析的url和已经解析过的url分开,以防重复解析
url_manager.py
class UrlManager():
def __init__(self):
self.new_urls=set()
self.old_urls=set()
#用来存储要爬的链接名
def add_new_url(self,url):
if url is None:
return
if url not in self.new_urls and url not in self.old_urls:
self.new_urls.add(url)
#用来存储URL下的所有的链接
def add_new_urls(self,urls):
if urls is None or len(urls)==0:
return
for url in urls:
self.new_urls.add(url)
#获取一个新的链接名,放入已经解析过的集合中
def get_new_url(self):
url=self.new_urls.pop()
self.old_urls.add(url)
return url
def has_new_urls(self):
return len(self.new_urls)!=0
url下载器,主要完成将url下载页面。主要通过的是urllib.request来完成
down_html.py
import urllib.request
class DownloadHtml():
def download(self,url):
if url is None:
return
response=urllib.request.urlopen(url)
#如何请求码不是200,则请求失败
if response.getcode()!=200:
return None
return response.read()
url解析器,对网页进行解析时我们需要知道我们要查询的内容都有哪些特征,我们可以打开一个网页点击右键审查元素来了解我们所查内容的共同之处。在利用BeautifulSoup时可以查询你的目标值
from bs4 import BeautifulSoup
import re
from urllib.parse import urljoin
class HtmlParse():
def parser_html(self,page_url,htm_cont):
if page_url is None and htm_cont is None:
return
#此处lxml解析能力比html.parse强,python3.2以上不需要下载
soup=BeautifulSoup(htm_cont,'lxml',from_encoding='utf-8')
new_urls=self.get_new_urls(page_url,soup)
new_data=self.get_new_data(page_url,soup)
return new_urls,new_data
def get_new_data(self,page_url,soup):
#res_data是用来存放获取数据的字典
res_data={"url":page_url}
#dd和div都是网页的标签,class同样也是网页中的类名。不同网页的获取也可修改
title_node=soup.find("dd",class_="lemmaWgt-lemmaTitle-title").find("h1")
res_data["title"]=title_node.get_text()
summary_node=soup.find("div",class_="lemma-summary")
res_data["summary"]=summary_node.get_text()
return res_data
def get_new_urls(self,page_url,soup):
new_urls=set()
#获取该页面下的.../item/.....的网页
links=soup.find_all("a",href=re.compile(r"/item/"))
for link in links:
new_url=link['href']
#将页面的名字补充完整,不然无法访问
new_full_url=urljoin(page_url,new_url)
new_urls.add(new_full_url)
return new_urls
URl输出器:选择你需要输出的格式进行输出,此处输出采取html的格式
class HtmlOutputer():
def __init__(self):
self.datas=[]
def collect_data(self,data):
if data is None:
return
self.datas.append(data)
def out_html(self):
with open("outputer.html",'w',encoding='utf-8') as fout:
fout.write("<html>")
fout.write("<meta charset='utf-8'>")
fout.write("<body>")
fout.write("<table>")
for data in self.datas:
fout.write("<tr>")
fout.write("<td>%s</td>"%data["url"])
fout.write("<td>%s</td>"%data["title"])
fout.write("<td>%s</td>"%data["summary"])
fout.write("</tr>")
fout.write("</table>")
fout.write("</body>")
fout.write("</html>")
最后,整合以上四大部分。
import url_manager
import down_html
import html_parse
import outputer
class SpiderMain():
def __init__(self):
self.urls=url_manager.UrlManager()
self.dowloader=down_html.DownloadHtml()
self.parese=html_parse.HtmlParse()
self.outputer=outputer.HtmlOutputer()
def craw(self,root_url):
#count只是用来计算你正在访问的是第几个网页
count=1
self.urls.add_new_url(root_url)
while self.urls.has_new_urls():
try:
#获取网页
new_url=self.urls.get_new_url()
print("crawing %d:%s"%(count,new_url))
#下载网页
html_cont=self.dowloader.download(new_url)
#解析网页
new_urls,datas=self.parese.parser_html(new_url,html_cont)
self.urls.add_new_urls(new_urls)
#输出数据
self.outputer.collect_data(datas)
if count==10:
break
count+=1
except:
print("craw failed")
# count+=1
#写入数据
self.outputer.out_html()
#调用主函数
if __name__=="__main__":
root_url = "http://baike.baidu.com/item/Python/407313"
obj_spider = SpiderMain()
obj_spider.craw(root_url)
结果展示:
注:在使用之前,请先安装bs4。windows系统使用命令行 pip install bs4 即可
如果你使用是pycharm,在setting===》tPythonProject下的Project interpreter===》点击加号添加新的库====》输入bs4添加也可以
本文引于 https://blog.csdn.net/qq_38520096/article/details/79189161
此外附上BeautifulSoup的中文文档:https://www.crummy.com/software/BeautifulSoup/bs4/doc.zh/