我们在进行爬虫时有的时候不可能只是在一个网站上进行内容上的爬取,理想中的爬虫应该是顺着一个链接从一个页面到另外一个页面,这需要获取页面上的所有的外链,同时收集每个页面上的内链。网站首页上不一定会发现外链,为了防止程序出错,就要递归深入到一个网站直到找到一个外链为止。
但在爬取的过程中出现了TimeoutError: [WinError 10060] 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。这个错误。
可能是由于访问网站频率过快,或者是我处于校园网,访问过快,被学校的服务的给限制了,或者是网速不好。所以在网上百度了下,设置了代理IP,结果完美运行,没有出现这个原因,最新的代理IP,自行百度即可。
附上代码:
#__author__ = 'Administrat
#coding=utf-8
from urllib.request import urlopen
from urllib.parse import urlparse
from bs4 import BeautifulSoup
import re
import datetime
import random
import io
import os
import sys
from urllib import request
import urllibpages = set()
random.seed(datetime.datetime.now())sys.stdout = io.TextIOWrapper(sys.stdout.buffer,encoding='gb18030')
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20100101 Firefox/23.0'}#获取页面所有内链的列表
def getInternalLinks(bsObj, includeUrl):includeUrl = urlparse(includeUrl).scheme+"://"+urlparse(includeUrl).netlocinternalLinks = []#找出所有以“/”开头的链接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 externalLinksdef getRandomExternalLink(startingPage):req=request.Request(startingPage,headers=headers)html=urlopen(req)bsObj=BeautifulSoup(html.read(),"html.parser")externalLinks = getExternalLinks(bsObj, urlparse(startingPage).netloc)if len(externalLinks) == 0:print("没有外部链接,准备遍历整个网站")domain = urlparse(startingPage).scheme+"://"+urlparse(startingPage).netlocinternalLinks = 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("随机外链是: "+externalLink)followExternalOnly(externalLink)#收集网站上发现的所有外链列表
allExtLinks = set()
allIntLinks = set()
def getAllExternalLinks(siteUrl):#设置代理IP访问proxy_handler=urllib.request.ProxyHandler({'http':'183.77.250.45:3128'})proxy_auth_handler=urllib.request.ProxyBasicAuthHandler()#proxy_auth_handler.add_password('realm', '123.123.2123.123', 'user', 'password')opener = urllib.request.build_opener(urllib.request.HTTPHandler, proxy_handler)urllib.request.install_opener(opener)req=request.Request(siteUrl,headers=headers)html=urlopen(req)bsObj=BeautifulSoup(html.read(),"html.parser")domain = urlparse(siteUrl).scheme+"://"+urlparse(siteUrl).netlocinternalLinks = getInternalLinks(bsObj,domain)externalLinks = getExternalLinks(bsObj,domain)#收集外链for link in externalLinks:if link not in allExtLinks:allExtLinks.add(link)#print(link)print("即将获取的外部链接的URL是:"+link)#收集内链for link in internalLinks:if link not in allIntLinks:print("即将获取内部链接的URL是:"+link)allIntLinks.add(link)getAllExternalLinks(link)#followExternalOnly("http://bbs.3s001.com/forum-36-1.html")
#allIntLinks.add("http://bbs.3s001.com/forum-36-1.html")
getAllExternalLinks("http://wangyou.pcgames.com.cn/zhuanti/lol/")
结果:
获取这些所有的外部链接之后,可以自行设置爬取某个页面上的什么东西,哈哈。
如果您觉得这篇博文有用,请访问我的个人站:http://www.stubbornhuang.com,更多博文干货等着您。