1、检查robots.txt

让爬虫了解爬取该网站时存在哪些限制。

最小化爬虫被封禁的可能,而且还能发现和网站结构相关的线索。

2、检查网站地图(robots.txt文件中发现的Sitemap文件)

帮助爬虫定位网站最新的内容,而无须爬取每一个网页。

网站地图提供了所有网页的链接,我们仍需对其谨慎处理,因为该文件经常存在缺失、过期或者不完整的问题。

3、估算网站大小

爬取效率(使用分布式)

方法:检查Google爬虫的结果(Google中搜索site:www.xxxxx.com/xxxxxx)

4、识别网站所用技术

builtwith模块

builtwith.parse(‘http://www.xxxxx.com’)

  • Web2py框架、通用JavaScript:内容嵌入在HTML中,容易抓取
  • AngularJS:动态加载
  • ASP.NET:会话管理和表单提交

5、寻找网站所有者

WHOIS协议查询域名的注册者

python-whois包

6、下载网页

urllib2模块(urllib模块)

urllib2.urlopen(url).read()

7、重试下载

4xx错误发生在请求存在问题时,5xx错误发生在服务端存在问题时。

5xx错误时重试下载。

num_retries 设定重试下载的次数

urllib2.URLError as e
e.reason
hasattr(e, ‘code’) and 500 <= e.code <600

8、设置用户代理

因为曾经历过质量不佳的Python网络爬虫造成的服务器过载,一些网站还会封禁这个默认的用户代理(Python-urllib/2.7)

user_agent = ‘Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36’
headers = {‘User-agent’: user_agent}
urllib2.Request(url, headers=headers)

9、解析robots.txt

robotparser模块

rp = rebotparser.RobotFileParser()
rp.set_url(url)
rp.read()
rp.can_fetch(user_agent, url)

10、支持代理(翻墙)

proxy = ’121.193.143.249:80’
opener = urllib2.build_opener()
proxy_params = {urlparse.urlparse(url).scheme: proxy}
opener.add_handler(urllib2.ProxyHandler(proxy_params))
response = opener.open(request)

11、下载限速

self.delay:延时限速

domain = urlparse.urlparse(url).netloc # 获取domain
last_accessed = self.domains.get(domain)
if self.delay > 0 and last_accessed is not None:
sleep_secs = self.delay - (datetime.now() - last_accessed).seconds
if sleep_secs > 0:
time.sleep(sleep_secs)
self.domains[domain] = datetime.now()

12、避免爬虫陷阱

深度 depth

最大深度 max_depth

max_depth = 2
seen = {}
depth = seen[url]
if depth != max_depth:
for link in links:
if link not in seen:
seen[link] = depth + 1
crawl_queue.append(link)

13、链接转换为绝对链接

urlparse模块

urlparse.urljoin(seed_url, link)

14、三种网页抓取方法

正则表达式:re.findall()

Beautiful Soup:

beautifulsoup4模块

soup = BeautifulSoup(html, ‘html.parser’)
soup.find()

Lxml:

lxml.html模块

tree = lxml.html.fromstring(html)
tree.cssselect()

15、磁盘缓存

  • pickle(输入转化为字符串)
  • zlib(压缩序列化字符串)
  • shutil(高层次的文件操作工具)
  • datetime(过期)
  • urlparse(文件名urlparse.urlsplit分割URL)

16、NoSQL

  • 列数据存储(HBase)
  • 键值对存储(Redis)
  • 面向文档的数据库(MongoDB)
  • 图形数据库(Neo4j)

17、数据库缓存

self.client = MongoClient('localhost', 27017) if client is None else client
self.db = self.client.cache
expires=timedelta(days=30)
self.db.webpage.create_index('timestamp', expireAfterSeconds=expires.total_seconds())

set方法:

from bson.binary import Binary # 二进制形式存储
record = {'result': Binary(zlib.compress(pickle.dumps(result))), 'timestamp': datetime.utcnow()}
self.db.webpage.update({'_id': url}, {'$set': record}, upsert=True)

get方法:

record = self.db.webpage.find_one({'_id': url})
pickle.loads(zlib.decompress(record['result']))

18、多线程爬虫

threads = []
while threads or crawl_queue:
for thread in threads:
if not thread.is_alive():
threads.remove(thread)
while len(threads) < max_threads and crawl_queue:
thread = threading.Thread(target=process_queue)
thread.setDaemon(True) # set daemon so main thread can exit when receives ctrl-c
thread.start()
threads.append(thread)
  time.sleep(SLEEP_TIME)

19、多进程爬虫

def process_crawler(args, **kwargs):
num_cpus = multiprocessing.cpu_count()
#pool = multiprocessing.Pool(processes=num_cpus)
print 'Starting {} processes'.format(num_cpus)
processes = []
for i in range(num_cpus):
p = multiprocessing.Process(target=threaded_crawler, args=[args], kwargs=kwargs)
#parsed = pool.apply_async(threaded_link_crawler, args, kwargs)
p.start()
processes.append(p)
# wait for processes to complete
for p in processes:
p.join()

20、动态网页进行逆向工程

ajax请求数据(数据接口API)

json解析成一个字典

21、渲染动态网页

  • WebKit渲染引擎(通过Qt框架可以获得该引擎的一个便捷Python接口)
  • Selenium(一个用于Web应用程序测试的工具)
  • PhantomJS(提供一个浏览器环境的命令行接口,你可以把它看作一个“虚拟浏览器”,除了不能浏览,其他与正常浏览器一样)

难点:需要等待AJAX请求完成之后才能加载结果,定义wait

22、表单交互

发送POST请求提交表单(重要部分cookie,cookie是网站在HTTP响应头中传输的少量数据)

def parse_form(html):
tree = lxml.html.fromstring(html)
data = {}
for e in tree.cssselect('form input'):
if e.get('name'):
data[e.get('name')] = e.get('value')
  return data
data = parse_form(html)
data['email'] = LOGIN_EMAIL
data['password'] = LOGIN_PASSWORD
encoded_data = urllib.urlencode(data)
request = urllib2.Request(LOGIN_URL, encoded_data)
response = opener.open(request)

23、使用cookie登录网站

cookie是网站在HTTP响应头中传输的少量数据,形如:Set-Cookie: session_id=example;。

浏览器将会存储这些数据,并在后续对该网站的请求头中包含它们。这样就可以让网站识别和跟踪用户。

import cookielib
cj = cookielib.CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
html = opener.open(LOGIN_URL).read()

24、从浏览器加载cookie(pprint美观打印数据结构)

import glob
import os # 返回session文件路径的辅助函数
def find_ff_sessions():
paths = [
'~/.mozilla/firefox/*.default', # Linux系统
'~/Library/Application Support/Firefox/Profiles/*.default', # OS X
'%APPDATA%/Roaming/Mozilla/Firefox/Profiles/*.default' # Windows Vista及以上版本
]
for path in paths:
filename = os.path.join(path, 'sessionstore.js')
matches = glob.glob(os.path.expanduser(filename))
if matches:
return matches[0]

glob模块会返回指定路径中所有匹配的文件。

# 把session解析到CookieJar对象的函数
def load_ff_sessions(session_filename):
cj = cookielib.CookieJar()
if os.path.exists(session_filename):
try:
json_data = json.loads(open(session_filename, 'rb').read())
except ValueError as e:
print 'Error parsing session JSON:', str(e)
else:
for window in json_data.get('windows', []):
for cookie in window.get('cookies', []):
import pprint; pprint.pprint(cookie)
c = cookielib.Cookie(0, cookie.get('name', ''), cookie.get('value', ''),
None, False,
cookie.get('host', ''), cookie.get('host', '').startswith('.'), cookie.get('host', '').startswith('.'),
cookie.get('path', ''), False,
False, str(int(time.time()) + 3600 * 24 * 7), False,
None, None, {})
cj.set_cookie(c)
else:
print 'Session filename does not exist:', session_filename
return cj

最后我们只需要使用浏览器cookie登录:

session_filename = find_ff_sessions()
cj = load_ff_sessions(session_filename)
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
html = opener.open(URL).read()

25、自动化表单处理(Mechanize--mechanize only works on python 2.x)

简化表单提交的高级模块Mechanize

不再需要管理cookie,而且访问表单输入框也更加容易。

import mechanize
br = mechanize.Browser()
br.open(login.LOGIN_URL)
br.select_form(nr=0)
br['email'] = login.LOGIN_EMAIL
br['password'] = login.LOGIN_PASSWORD
response = br.submit()

26、验证码处理(光学字符识别(COR)运用在验证码像素基本一致、字体标准、限制在字典中的单词)

from io import BytesIO
import lxml.html
from PIL import Image # 返回包含验证码图像的Image对象
def extract_image(html):
tree = lxml.html.fromstring(html)
img_data = tree.cssselect('div#recaptcha img')[0].get('src')
# remove data:image/png;base64, header
img_data = img_data.partition(',')[-1]
#open('test_.png', 'wb').write(data.decode('base64'))
binary_img_data = img_data.decode('base64')
file_like = BytesIO(binary_img_data)
img = Image.open(file_like)
#img.save('test.png')
return img
import pytesseract

# 阈值化,抽取验证码中的文本
def ocr(img):
gray = img.convert('L')
bw = gray.point(lambda x: 0 if x < 1 else 255, '')
word = pytesseract.image_to_string(bw)
ascii_word = ''.join(c for c in word if c in string.letters).lower()
return ascii_word

27、处理复杂验证码(验证码处理API)

  • 2captcha.com
  • deathbycaptcha.com
  • 9kw.eu(可以不需要花钱)

28、Scrapy(一个流行的网络爬虫框架,可保存结果、中断恢复爬虫)

Scrapy拥有很多简化网站抓取的高级函数

scrapy -h 查看命令的详细信息

  1. startproject:创建一个新项目
  2. genspider:根据模板生成一个新爬虫
  3. crawl:执行爬虫
  4. shell:启动交互式抓取控制台

29、Portia(一款基于Scrapy开发的开源工具)

该工具可以通过点击要抓取的网站部分来创建爬虫,这样就比手工创建CSS选择器的方式更加方便。

30、Scrapely库

使用训练数据建立从网页中抓取哪些内容的模型,并在以后抓取相同结构的其他网页时应用该模型。

from scrapely import Scraper

s = Scraper()
train_url = ‘http://www.xxxxx.com/xxxxxx’
s.train(train_url, {‘name’: ‘xxx’, ‘population’: ‘xxxx’})
test_url = ‘xxxxxxx’
s.scrape(test_url)

网页内容是静态的,在布局发生改变时,这种方法就会非常有用。

31、反爬虫

为什么?

  1. 爬虫占总PV比例较高,这样浪费钱(尤其是三月份爬虫)。
  2. 公司可免费查询的资源被批量抓走,丧失竞争力,这样少赚钱。
  3. 爬虫是否涉嫌违法? 如果是的话,是否可以起诉要求赔偿?这样可以赚钱。

怎么做?

  • 后台对访问进行统计,如果单个IP或userAgent访问超过阈值,予以封锁。
  • 验证码、Ajax异步加载、Noscript标签的使用、Cookie限制

Python网络爬虫学习总结的更多相关文章

  1. python网络爬虫学习笔记

    python网络爬虫学习笔记 By 钟桓 9月 4 2014 更新日期:9月 4 2014 文章文件夹 1. 介绍: 2. 从简单语句中開始: 3. 传送数据给server 4. HTTP头-描写叙述 ...

  2. Python网络爬虫学习手记(1)——爬虫基础

    1.爬虫基本概念 网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本.--------百度百科 简单的说,爬 ...

  3. python网络爬虫学习

    网络爬虫 Requests官方中文教程地址:http://docs.python-requests.org/zh_CN/latest/user/quickstart.html Beautiful So ...

  4. python网络爬虫学习笔记(一)Request库

    一.Requests库的基本说明 引入Rquests库的代码如下 import requests 库中支持REQUEST, GET, HEAD, POST, PUT, PATCH, DELETE共7个 ...

  5. python网络爬虫学习笔记(二)BeautifulSoup库

    Beautiful Soup库也称为beautiful4库.bs4库,它可用于解析HTML/XML,并将所有文件.字符串转换为'utf-8'编码.HTML/XML文档是与“标签树一一对应的.具体地说, ...

  6. 第3次作业-MOOC学习笔记:Python网络爬虫与信息提取

    1.注册中国大学MOOC 2.选择北京理工大学嵩天老师的<Python网络爬虫与信息提取>MOOC课程 3.学习完成第0周至第4周的课程内容,并完成各周作业 4.提供图片或网站显示的学习进 ...

  7. 第三次作业-MOOC学习笔记:Python网络爬虫与信息提取

    1.注册中国大学MOOC 2.选择北京理工大学嵩天老师的<Python网络爬虫与信息提取>MOOC课程 3.学习完成第0周至第4周的课程内容,并完成各周作业 第一周 Requests库的爬 ...

  8. 学习推荐《精通Python网络爬虫:核心技术、框架与项目实战》中文PDF+源代码

    随着大数据时代的到来,我们经常需要在海量数据的互联网环境中搜集一些特定的数据并对其进行分析,我们可以使用网络爬虫对这些特定的数据进行爬取,并对一些无关的数据进行过滤,将目标数据筛选出来.对特定的数据进 ...

  9. 假期学习【六】Python网络爬虫2020.2.4

    今天通过Python网络爬虫视频复习了一下以前初学的网络爬虫,了解了网络爬虫的相关规范. 案例:京东的Robots协议 https://www.jd.com/robots.txt 说明可以爬虫的范围 ...

随机推荐

  1. alien 进行rpm 包和deb 包之间的转换

    今天安装一个pandoc, 官方只提供了一个deb 的二进制包,为了在redhat 上安装,需要将deb 包转换成rpm 包. 使用工具alien : http://ftp.de.debian.org ...

  2. win7笔记本电脑怎么做wifi热点

    win7设置wifi热点后非常方便,可以给其他笔记本和手机之类支持无线上网的移动设备使用,接下来请看超简单的详细设置方法. 方法/步骤 1 第一步先打开“控制面板” 2 点击“网络和Internet” ...

  3. js正则表达式的应用

    JavaScript表单验证email,判断一个输入量是否为邮箱email,通过正则表达式实现. //检查email邮箱 function isEmail(str){ var reg = /^([a- ...

  4. 关于NoSQL与SQL的区别

    简单说来:sql是关系型数据库的结构化查询语言,而nosql,一般代指菲关系型数据库,sql语句就不能用来,不过有些有leisql的查询语言,且nosql数据库没有统一的查询语言. 相关参考文章阅读: ...

  5. JBPM4.4_管理流程定义

    1. 管理流程定义 没有更新功能 1.1. 部署流程定义 注意区分Deployment与ProcessDefinition 1.1.1. 示例代码1:流程定义有关文件在classpath中 Strin ...

  6. 超全面的JavaWeb笔记day15<mysql数据库>

    1.数据库的概述 2.SQL 3.DDL 4.DML 5.DCL 6.DQL MySQL 数据库 1 数据库概念(了解) 1.1 什么是数据库 数据库就是用来存储和管理数据的仓库! 数据库存储数据的优 ...

  7. K - problem 问题

    Leetcode 有几个题目, 分别是 2sum, 3sum(closest), 4sum 的求和问题和 single Number I II, 这些题目难点在于用最低的时间复杂度找到结果 2-sum ...

  8. MUI Hbuilder设置模拟器运行APP项目

    1 安装hbuilder和夜神模拟器 2 hbuilder  新建app项目 3 hbuilder:运行-> 设置web服务器->Hbuilder 第三方安卓模拟器端口:62001 4 运 ...

  9. Servlet MVC 项目实战实例

    MVC的架构模式,一直是JavaEE开发中所遵循的标准,如今很多框架都已经很好的实现了MVC,像大家所熟知的Struts,SpringMVC,JSF等,但是如果没有任何框架的支持,仅仅通过JavaWe ...

  10. HTTP/2探索第二篇——工具及应用

    版权声明:本文由张浩然原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/88 来源:腾云阁 https://www.qclou ...