爬虫总结

来源:互联网 发布:淘宝网女裤 编辑:程序博客网 时间:2024/06/05 15:39

爬虫相关内容总结

理论

互联网协议入门(一)

互联网协议入门(二)

TCP 协议简介

分布式爬虫

requests + redis

这个比较简单,基本思路就是用 redis 做队列,一个爬虫放链接,其它爬虫都从里面取
链接就行了。

scrapy + redis

网上有一个写好的,地址是 https://github.com/rmax/scrapy-redis

安装

git clone https://github.com/rmax/scrapy-redis.gitcd scrapy-redispython setup.py install

使用

  • 配置

settings.py 文件中加入下面几句话,这几个是关键配置,其它配置自行查阅上面
的链接

REDIS_HOST = '192.168.8.144'REDIS_PORT = 6379SCHEDULER = 'scrapy_redis.scheduler.Scheduler'DUPEFILTER_CLASS = 'scrapy_redis.dupefilter.RFPDupeFilter'

这几行配置主要是替换掉了 scrapy 的默认调度器和去重队列。

  • spider 的写法

方法一、让你的 spider 继承自 scrapy_redis.spiders.RedisSpider

作者原意是让 RedisSpider 作为从爬虫,并且这个爬虫如果不是被终止的话会一直
处于等待状态,不会退出。所以需要写个主程序往 redis 的队列里放东西,还要手动去关闭
从爬虫。可以通过覆盖 start_requests 方法来直接让从爬虫自己往队列放东西,可以
修改源代码相应部分(site-packages/scrapy_redis/spiders.py)来让从爬虫尝试特定
次数就退出,但是这太麻烦,所以推荐直接用第二种方法。

方法二、spider 仍然继承自 scrapy.Spider

用这种方法需要注意的是一定要覆盖掉 start_requests 方法,因为这个方法的默认
行为是不去重的(dont_filter=True)。这种方法的原理是利用 Redis 的去重队列去掉
重复的数据,如下例所示,

class MySpider(scrapy.Spider):    start_urls = ['http://a.com', 'http://www.b.com']    def start_requests(self):        for url in self.start_urls:            yield scrapy.Requests(                url,                callback=self.parse,                dont_filter=False            )    def parse(self, response):        pass

虽然每个爬虫都会遍历 start_urls,但是后访问的会被去重队列去掉,所以最终其实
只发起了两次请求,即 http://a.comhttp://www.b.com 各一次。

这样写的好处是把同一份代码直接拷贝到不同的机器上直接运行就是分布式爬虫了,你所
做的工作只是加了几行配置。

登录

scrapy.FormRequest

login.py

class LoginSpider(scrapy.Spider):    name = 'login_spider'    start_urls = ['http://www.login.com']    def parse(self, response):        return [            scrapy.FormRequest.from_response(                response,                # username 和 password 根据实际页面的表单的 name 字段进行修改                formdata={'username': 'your_username', 'password': 'your_password'},                callback=self.after_login            )        ]    def after_login(self, response):        # 登录后的代码        pass

get_cookie_by_selenium.py

import pickleimport timefrom selenium import webdriverdef get_cookies():    url = 'https://www.test.com'    web_driver = webdriver.Chrome()    web_driver.get(url)    username = web_driver.find_element_by_id('login-email')    username.send_keys('username')    password = web_driver.find_element_by_id('login-password')    password.send_keys('password')    login_button = web_driver.find_element_by_id('login-submit')    login_button.click()    time.sleep(3)    cookies = web_driver.get_cookies()    web_driver.close()    return cookiesif __name__ == '__main__':    cookies = get_cookies()    pickle.dump(cookies, open('cookies.pkl', 'wb'))

获取浏览器 cookie(以 Ubuntu 的 Firefox 为例)

get_cookie_by_firefox.py

import sqlite3import pickledef get_cookie_by_firefox():    cookie_path = '/home/name/.mozilla/firefox/bqtvfe08.default/cookies.sqlite'    with sqlite3.connect(cookie_path) as conn:        sql = 'select name,value from moz_cookies where baseDomain="test.com"'        cur = conn.cursor()        cookies = [{'name': name, 'value': value} for name, value in cur.execute(sql).fetchall()]        return cookiesif __name__ == '__main__':    cookies = get_cookie_from_firefox()    pickle.dump(cookies, open('cookies.pkl', 'wb'))
cookies = pickle.load(open('cookies.pkl', 'rb'))yield scrapy.Request(url, cookies=cookies, callback=self.parse)
cookies = pickle.load(open('cookies.pkl', 'rb'))s = requests.Session()for cookie in cookies:    s.cookies.set(cookie['name'], cookie['value'])
from selenium import webdrivercookies = pickle.load(open('cookies.pkl', 'rb'))w = webdriver.Chrome()# 直接添加cookie会报错,下面是一种解决方案,可能有更好的# -- start --w.get('http://www.test.com')w.delete_all_cookies()# -- end --for cookie in cookies:    w.add_cookie(cookie)

防反爬

如何不被禁: https://www.zhihu.com/question/28168585

如何检测爬虫:http://bigsec.com/bigsec-news/anan-20161026-fanpachongwangzhan

调试工具

  1. 浏览器自带的开发者工具
  2. mitmproxy,使用不难,可以自行搜索安装和配置方法