今天学习了python网络爬虫的简单知识

首先是一个爬取百度的按行读取和一次性爬取

逐行爬取

for line in urllib.request.urlopen("http://www.baidu.com"):
print(line.decode("utf-8"))

全部爬取

mystr = urllib.request.urlopen("http://www.baidu.com").read()
print(mystr.decode("utf-8"))

分别用栈和队列实现了DFS和BFS的邮箱爬取

用队列deque实现BFS

import re
import urllib
import urllib.request
from collections import deque def getallemail(data): #邮箱的正则表达式获取所有的邮箱
try:
mailregex = re.compile(r"([A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4})", re.IGNORECASE)
mylist = mailregex.findall(data)
return mylist
except:
return [] def getdata(url): #用utf-8编码读取url返回网页源代码
try:
data = urllib.request.urlopen(url).read().decode("utf-8")
return data
except:
return "" def geteveryurl(data): #获得网页所有的url
alllist = []
mylist1 = getallhttp(data)
mylist2 = []
if len(mylist1)>0:
mylist2 = getabsurl(mylist1[0],data) #mylist[0]作用是提取元素
alllist.extend(mylist1)
alllist.extend(mylist2)
return alllist def gethostname(httpstr):
try:
mailregex = re.compile(r"(http://\S*?)/",re.IGNORECASE) #预编译提取主机名的regex
mylist = mailregex.findall(httpstr)
if len(mylist)==0:
return None
else:
return mylist[0]
except:
return None def getabsurl(url,data):
try:
regex = re.compile("href=\"(.*?)\"",re.IGNORECASE) #预编译提取href正则表达式
httplist = regex.findall(data)
newhttplist = httplist.copy() #进行一次深拷贝,以进行后面的删除行为
for data in newhttplist:
if data.find("http://")!=-1: #如果其中包含http
httplist.remove(data) #在原list中remove此data
if data.find("javascript")!=-1:
httplist.remove(data) #同理
hostname = gethostname(url)
if hostname!=None:
for i in range(len(httplist)):
httplist[i] = hostname + httplist[i]
return httplist
except:
return [] def getallhttp(data):#找到所有的http
try:
mailregex = re.compile(r"(http://\S*?)[\"|>|)]",re.IGNORECASE)
mylist = mailregex.findall(data)
return mylist
except:
return[] def BFS(urlstr):
urlqueue = deque([]) #新建一个队列
urlqueue.append(urlstr) #队列中加入最初的url
while len(urlqueue)!=0: #判断队列是否为空
url = urlqueue.popleft() #队列弹出的数据(url)
print(url) #打印url连接
pagedata = getdata(url) #获取网页源代码
emaillist = getallemail(pagedata) #提取邮箱到列表
if len(emaillist)!=0: #若邮箱列表不为空
for email in emaillist:
print(email) #打印所有的邮箱
newurllist = geteveryurl(pagedata) #抓取该网页的所有的url
if len(newurllist)!=0: #若列表不为空
for urlstr in newurllist:
if urlstr not in urlqueue:
urlqueue.append(urlstr) #若url不在该队列中,则将该url加入队列中 BFS(input("请输入你想爬取的最初页面"))

用栈stack实现DFS

import re
import urllib
import urllib.request def getallemail(data): #邮箱的正则表达式获取所有的邮箱
try:
mailregex = re.compile(r"([A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4})", re.IGNORECASE)
mylist = mailregex.findall(data)
return mylist
except:
return [] def getdata(url): #用utf-8编码读取url返回网页源代码
try:
data = urllib.request.urlopen(url).read().decode("utf-8")
return data
except:
return "" def geteveryurl(data): #获得网页所有的url
alllist = []
mylist1 = getallhttp(data)
mylist2 = []
if len(mylist1)>0:
mylist2 = getabsurl(mylist1[0],data) #mylist[0]作用是提取元素
alllist.extend(mylist1)
alllist.extend(mylist2)
return alllist def gethostname(httpstr):
try:
mailregex = re.compile(r"(http://\S*?)/",re.IGNORECASE) #预编译提取主机名的regex
mylist = mailregex.findall(httpstr)
if len(mylist)==0:
return None
else:
return mylist[0]
except:
return None def getabsurl(url,data):
try:
regex = re.compile("href=\"(.*?)\"",re.IGNORECASE) #预编译提取href正则表达式
httplist = regex.findall(data)
newhttplist = httplist.copy() #进行一次深拷贝,以进行后面的删除行为
for data in newhttplist:
if data.find("http://")!=-1: #如果其中包含http
httplist.remove(data) #在原list中remove此data
if data.find("javascript")!=-1:
httplist.remove(data) #同理
hostname = gethostname(url)
if hostname!=None:
for i in range(len(httplist)):
httplist[i] = hostname + httplist[i]
return httplist
except:
return [] def getallhttp(data):#找到所有的http
try:
mailregex = re.compile(r"(http://\S*?)[\"|>|)]",re.IGNORECASE)
mylist = mailregex.findall(data)
return mylist
except:
return[] def DFS(urlstr):
visitlist = [] #代表已经访问过的url,防止深度遍历出现死循环
urlstack=[] #栈
urlstack.append(urlstr)
while len(urlstack)!=0:
url = urlstack.pop()
print(url) #打印url链接
if url not in visitlist:
pagedata = getdata(url)
emaillist = getallemail(pagedata)
if len(emaillist)!=0:
for email in emaillist:
print(email)
newurllist = geteveryurl(pagedata)
if len(newurllist)!=0:
for urlstr in newurllist :
if urlstr not in urlstack:
urlstack.append(urlstr)
visitlist.append(url) DFS(input("请输入你想爬取的最初页面")) #提取数据容易出现广度遍历
#深度遍历容易出现死循环
  • 其中需要注意的是,DFS容易出现死循环现象,故使用visitlist来避免,数据提取适合使用广度遍历实现,因为深度遍历是一撸到底,适合挖掘网站的层数。

代码来自尹成python教学

最新文章

  1. JavaScript模板引擎artTemplate.js——template.compile()方法
  2. 两个不同的list随机组合到一个List中。
  3. codeforces 721C C. Journey(dp)
  4. zw版【转发·台湾nvp系列例程】HALCON MirrorRegion (Delphi)
  5. android 下滤镜效果的实现
  6. H5神器之canvas应用——网页修改保存图片
  7. ubuntu:configure error:cannot find ssl libraries
  8. JavaBean和EJB的区别
  9. Android开发中一些常见的问题解决方案
  10. dojo事件
  11. WPF技术触屏上的应用系列(三): 视频播放器的使用及视频播放、播放、暂停、可拖动播放进度效果实现
  12. redis加入windows服务自启动
  13. windows下tomcat zip解压版安装方法
  14. Oracle RAC + ASM + Grid安装
  15. anaconda安装opencv(python)
  16. Promise的两种处理异步的方式
  17. python基础---面向对象的概念
  18. linux使用framebuffer的代码
  19. Android Studio 合并分支代码到主干的操作总结
  20. ResourceBundle读取properties配置文件

热门文章

  1. VueCli4构建项目如何配置文件路径别名?
  2. Java——日期格式化YYYYMMdd与yyyyMMdd的区别
  3. APP元素定位和操作
  4. protocbuf的简单理解
  5. 开心一下-实现基于Java一个中文编程语言
  6. JAVASE(十五) 泛型 :泛型用例、自定义泛型类、通配符
  7. JAVASE(十)面向对象:特性之多态性、Object类、代码块、关键字:static、final、父子类执行顺序
  8. MyBatis(二)参数传递和自定义结果集
  9. CentOS 虚拟机 下载及 搭建
  10. Java实现 LeetCode 775 全局倒置与局部倒置(分析题)