一、辅助工具
BeautifulSoup 库 :一款优秀的HTML/XML解析库,采用来做爬虫,不用考虑编码,还有中日韩文的文档,其社区活跃度之高,可见一斑。[注] 这个在解析的时候需要一个解析器,在文档中可以看到,推荐lxml
Requests 库:一款比较好用的HTTP库,当然python自带有urllib以及urllib2等库。
Fiddler工具:这是一个HTTP抓包软件,能够截获所有的HTTP通讯。
二、知识点
1、流程
发起请求
通过HTTP库向目标站点发起请求,也就是发送一个Request,请求可以包含额外的header等信息,等待服务器响应
获取响应内容
如果服务器能正常响应,会得到一个Response,Response的内容便是所要获取的页面内容,类型可能是HTML,Json字符串,二进制数据(图片或者视频)等类型
解析内容
得到的内容可能是HTML,可以用正则表达式,页面解析库,beautifulsoup进行解析,可能是Json,可以直接转换为Json对象解析,可能是二进制数据,可以做保存或者进一步的处理
保存数据
保存形式多样,可以存为文本,也可以保存到数据库,或者保存特定格式的文件
2、BeautifulSoup的find( )和findAll( )
findAll(tag, attributes, recursive, text, limit, keywords)
find(tag, attributes, recursive, text, keywords)
- tag - 查找的标签 (常用)
- attributes - 查找标签的属性 (常用)
- recursive - 是否查找全部子标签
- text - 查找内容为text的标签的数量
- limit - =1时,findAll()相当于find()
- keywords - 可以让你选择那些具有指定属性的标签(class因为是关键字,换为class_)
3、BeautifulSoup库对象
- BeautifulSoup 对象
- 标签 Tag 对象 :BeautifulSoup 对象通过 find 和 findAll,或者直接调用子标签获取的一列对象或单个对象
- NavigableString 对象:用来表示标签里的文字,不是标签(有些函数可以操作和生成 NavigableString 对象, 而不是标签对象)。
- Comment 对象:用来查找 HTML 文档的注释标签,< !-- 像这样 – >
4、正则表达式
5、获取属性
- 对于一个标签对象,可以用下面的代码获取它的全部属性
- myTag.attrs
- 要注意这行代码返回的是一个 Python 字典对象,可以获取和操作这些属性。比如要获取图 片的资源位置 src
- myTag.attrs[“src”]
6、链接去重(使用set)
三、获取网络的内外链(有bug未修)
from urllib.request import urlopen
from urllib.parse import urlparse
from bs4 import BeautifulSoup
import re
import datetime
import random
pages = set()
random.seed(datetime.datetime.now())
# 获取页面所有内链的列表
def getInternalLinks(bsObj, includeUrl):
includeUrl = urlparse(includeUrl).scheme+"://"+urlparse(includeUrl).netloc
internalLinks = []
# 找出所有以"/"开头的链接
for link in bsObj.findAll("a", href=re.compile("^(/|.*"+includeUrl+")")):
if link.attrs['href'] is not None:
if link.attrs['href'] not in internalLinks:
if(link.attrs['href'].startswith("/")):
internalLinks.append(includeUrl+link.attrs['href'])
else:
internalLinks.append(link.attrs['href'])
return internalLinks
# 获取页面所有外链的列表
def getExternalLinks(bsObj, excludeUrl):
externalLinks = []
# 找出所有以"http"或"www"开头且不包含当前URL的链接
for link in bsObj.findAll("a", href=re.compile("^(http|www)((?!"+excludeUrl+").)*$")):
if link.attrs['href'] is not None:
if link.attrs['href'] not in externalLinks:
externalLinks.append(link.attrs['href'])
return externalLinks
def splitAddress(address):
addressParts = address.replace("http://", "").split("/")
return addressParts
# 通过一个链接返回获得外部链接列表中的随机一个
def getRandomExternalLink(startingPage):
html = urlopen(startingPage)
bsObj = BeautifulSoup(html, "lxml")
# urlparse : 将url分为6个部分,返回一个包含6个字符串项目的元组:协议、位置、路径、参数、查询、片段
# 例如 :
# 分别是 : scheme='https', netloc='i.cnblogs.com', path='/EditPosts.aspx', params='', query='opt=1', fragment=''
externalLinks = getExternalLinks(bsObj, urlparse(startingPage).netloc)
if len(externalLinks) == 0:
print("No external links, looking around the site for one")
domain = urlparse(startingPage).scheme+"://"+urlparse(startingPage).netloc
internalLinks = getInternalLinks(bsObj, domain)
return getRandomExternalLink(internalLinks[random.randint(0, len(internalLinks)-1)])
else:
return externalLinks[random.randint(0, len(externalLinks)-1)]
# 递归输出每一个外链
def followExternalOnly(startingSite):
externalLink = getRandomExternalLink(startingSite)
print("Random external link is: "+externalLink)
followExternalOnly(externalLink)
followExternalOnly("")