scrapy实战笔记

一,基础

scrapy优势:异步IO,性能强;内置功能丰富(css,xpath);易扩展
爬虫简要步骤:URL分析,数据爬取分析逻辑开发,数据储存(数据库),反爬虫策略。
注意事项:注意不要违法(关闭robot协议,不违法)
其他相关知识:virtualenv,正则,编码(ASCII, unicode, UTF-8)
字符串编码知识:

WX20200204-151821@2x.png

WX20200204-160154@2x.png

二,xpath

1,xpath语法
respone.xpath返回的是select元素,可以继续使用xpath.
select元素的extract()方法,提取对象的值的数组,由于一般取数组的第一项,故可以使用extract_first()
例子:respone.xpath().extract()[0] <===> respone.xpath().extract_first()
比较:前者需要异常处理(数组为空的情况),后者有默认返回None,所以优先使用后者

  • xpath中使用XSLT元素和函数,例如:response.xpath('//h1/text()'),其中text()就是XSLT函数
  • 元素有多个class时,仅仅写//span[@class="xxx"],可能匹配不到,可以写//span[contains(@class, 'xxx')]
    -尽量通过class或者id选择元素,不要使用绝对选择,比如/html/body/div[3]/h1/div/span
    有的元素是动态JS插入的,绝对选择很容易出错

2,scrapy shell url
测试xpath可以在命令行使用如上命令,比打断点调试快
3,css选择器
例子:response.css('.xxx h1::text').extract()
提取class为xxx的元素中的h1中的文本
还有很多其他尾类选择器,常用的如::attr(href),获取a标签的href属性

三,url提取

1,运用urllib中的parse
parse.urljoin(baseurl, target):会自动提取baseURL中的域名与target结合
2,scrapy.http中的Request
使用这个Request可以将新获取的url传递给scrapy,参数有url, callback,还可以增加meta,给callback传餐,获取meta参数,使用response.meta['xxx'],或者使用字典的get方法,避免错误

四,items➡️格式化 和 pipeline➡️数据存储

1,item中定义要获取的数据字段,然后在spider中创建item类的实例,并讲相关的值以字典的形式赋值给item实例。
调用yield item实例,这些字段就会在pipeline中处理
2,配置pipeline,以及优先级,越小越先进入pipeline处理
每个pipeline要return item,最后将数据存储到DB,或者使用codecs包,保存到文件
3,item loader
add_css(‘name', '规则')
add_xpath(‘name', '规则')
add_value(‘name', 值)
item_loader.load_item() 解析规则,生成item实例
注意:生成的item实例,每个字段的值都是list,而且没有特异化处理
解决:在 xx = scrapy.field() 中用scrapy.loader.processors中的MapCompose预处理数据,接收多个函数,依次处理

五,模拟登陆

使用requests库和cookie

try
  import cookielib
except:
  import http.cookiejar as cookie # python3

六,反爬虫

1,UA
不建议使用fake_useragent,不好用
在网上找个UA的list,随机取就好
2,IP代理(通过代理服务器)(西次IP代理)
在中间件:request.meta['proxy'] = '西次的IP代理'
爬取所有高密的IP代理,构造IP代理池
GitHub ---> scrapy proxy 现成的轮子
3,验证码识别 (略过,后面补)
人工打码 && 在线打码

七,动态网站爬取selenium

selenium英文文档
selenium中文文档
其实这一块看文档足够,简单,而且文档比较好

Chromedriver使用教程

selenium适用于自动化测试,完全满足爬取动态网页,模拟点击,模拟登陆等功能
下载Chromedriver,编写脚本模拟浏览器加载,获取浏览器解析后的代码,即可。


企业微信20200212050144.png

1,常用方法
browser.find_elemnt_by_xxxx() xxx有css,xpath,node,id等等多种方法
browser.find_elemnt_by_xxxx().send_keys() 如果选取的是input,这个方法就是输入值
browser.find_elemnt_by_xxxx().click() 模拟点击
browser.execute_script(‘window.scrollTo(0, document.body.scrollHeight);var a=10;') 运行JS代码,做一些滚动等动作,便于爬取微博这种滚动加载的页面

2,不加载图片
当不需要加载图片时,使用此功能可以提高爬虫速度
这个方法文档中并没有,可以去读源码,结合文档自己分析

from selenium import webdriver
prefs = { "profile.managed_default_content_settings.images":2 }

chrome_opt = webdriver.ChromeOptions()
chrome_opt.add_experimental_option("prefs", prefs)

browser = webdriver.Chrome(executable_path="path", chrome_opt=chrome_opt)
browser.get("url")

3,selenium集成到scrapy
通过scrapy的middleware中的process_request,使request通过selenium的get来请求,最后return 一个scrapy.http中的HtmlResponse即可(scrapy就不会再处理了)
代码如下:通过注释,已经解释了为什么这么写,这么写的好处

class DigeSpiderSpiderMiddleware(object):
    # Not all methods need to be defined. If a method is not defined,
    # scrapy acts as if the spider middleware does not modify the
    # passed objects.
    def __init__(self):
        # 每个爬虫只开一次浏览器
        # 放到spider中,保证了每个 有需要的spider单独开浏览器,不影响其他spider,还可以提高并发效率
        self.browser = webdriver.Chrome(executable_path='/Users/chaos/desktop/chromedriver')
        # super(DigeSpiderSpiderMiddleware, self).__init__()
        dispatcher.connect(self.spider_closed, signals.spider_closed)

    def spider_closed(self):
        # 通过信号与槽,当spider关闭时,关闭浏览器
        self.browser.quit()

class chrome_filter(object):

    def process_request(self, request, spider):
        if spider.name == 'price_info_spider':
            spider.browser.get(request.url)
            time.sleep(2)
            spider.browser.execute_script('window.scrollTo(0, document.body.scrollHeight);var a=10;') # 向下滚动页面
            time.sleep(2)
            return HtmlResponse(url=spider.browser.current_url, body=spider.browser.page_source, encoding='utf-8')

有待提升部分:time的sleep降低了scrapy的效率,最好能改写为异步的。这不敷需要重写scrapy的downloader。我暂不考虑

八,redis缓存打造分布式爬虫

原理:使用redis缓存多个服务器爬虫的url去重逻辑和request队列
优势:多个服务器(IP),速度与安全都极大提升

九,扩展,elasticsearch打造企业级搜索引擎

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,569评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,499评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,271评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,087评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,474评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,670评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,911评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,636评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,397评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,607评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,093评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,418评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,074评论 3 237
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,092评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,865评论 0 196
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,726评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,627评论 2 270

推荐阅读更多精彩内容