python3爬虫学习系列02-常见的下载和抽取网页的方法

一、3种常见的爬取网站的方法

首先我们需要下载网站中需要的网页,通常下载网站的网页有如下3种方式:

  1. 爬取网站地图(sitemap)
  2. 遍历每个网页的数据库ID
  3. 跟踪网页链接
    在python3中将python2中的urllib和urllib2合并为urllib。

1. 爬取网站地图(sitemap)

适用情况:所爬取的网站中有网站地图(sitemap)。
适用正则表达式或是CSS选择器从sitemap中抽取出url,爬取这些url。
优点:简单便捷。
缺点:无法通过sitemap获取到每个网页的链接,而且可能有的网站没有sitemap,无法保证这种方法始终可用。

2. 遍历每个网页的数据库ID

适用情况:能够找到网站url的结构和规律。
分析该网站下的url的规律,根据这些规律构建出url,爬取这些url。
优点:便捷。
缺点:无法保证始终可用,有的网站的url规律较为复杂,使用ID来遍历爬取url效率太低。

3. 跟踪网页链接(常用)

其实现在,使用的user_agent可以用python3的一个包,叫作Fake-useragent,很方便。

适用情况:贼拉广。
优点:能够下载整个网站的页面。
缺点:会下载大量我们并不需要的网页。

import re
import urllib
from urllib import parse

def link_crawl(seed_url, link_regex, max_depth=1):
	"""
	:param seed_url: 种子url,爬取的原始url
	:param link_regex: 匹配url的正则表达式
	:param max_depth: 爬虫的最大深度,例如父页面深度为1,其子页面为2,子页面的子为3,依次类推
	"""
	# 一个列表保存需要爬取的url,可以理解成一个队列
	crawl_queue = [seed_url]
	# 保存已经加入待爬取队列的url
	seen = {}
	
	while crawl_queue:
		url = crawl_queue.pop()
		# 这个url代表的网页的深度
		depth = seen[url]
		if depth <= max_depth:
			html = download(url)
			for link in get_links(html):
				# 相对链接=>绝对链接
				link = parse.urljoin(seed_url, link)
				if link not in seen:
					seen[link] = depth + 1
					crawl_queue.append(link)

def download(url, user_agent='wswp', proxy=None, num_retries=2):
	"""
	:param url: 待下载的url
	:param user_agent: 用户代理,表明用户以什么方式来访问的这个url
	:param proxy: 代理
	:param num_retries: 重试次数,下载失败超过这个次数则不在下载此url
	"""
	print('Downloading: {}'.format(url))
	headers = {'User-Agent': user_agent}
	request = urllib.request.Request(url, headers=headers)
	
	opener = urllib.request.build_opener()
	if proxy:
		proxy_params = {parse.urlparse(url}.scheme: proxy}
		opener.add_handler(urllib.request.ProxyHandler(proxy_params))
	try:
		html = opener.open(request).read()
	except urllib.error.URLError as e:
		print('Download error: {}'.format(e.reason))
		html = None
		
		if num_retries > 0:
			# 返回状态码是5xx则重试
			if hasattr(e, 'code') and 500 <- e.code < 600:
				html = download(url, user_agent, proxy, num_retries-1)
	return html

def get_links(html):
	"""
	从html返回url列表
	"""
	webpage_regex = re.compile('<a[^>]+href=["\'](.*?)["\']', re.IGNORECASE)
	return webpage_regex.findall(html)
				
		

二、3中抽取网页数据的方法

在获取到了指定网页的html数据之后,我们需要从html中抽取出需要的数据,扔掉无用的数据。这个过程叫作抓取(scraping)。

  1. 正则表达式

优点:抽取性能快。
缺点:使用难度较大,而且正则表达式来抽取网页数据这种方法比较脆弱,若网页结构发生改变,容易失效。

  1. Beautiful Soup

优点:更健壮,即使网页结构发生改变,仍然能够有效使用。
缺点:抽取性能慢。

  1. lxml

优点:抽取性能快。
缺点:使用较Beautiful Soup复杂,但是较正则表达式简单。

通常情况下,lxml是抓取数据的最好选择,这是因为该方法既快又健壮,而正则表达式和Beautiful Soup只能在某些特定场景下有用。

三、参考文献

[1] 《用python写网络爬虫(web scraping with python)》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值