20181009_Scrapy源码第四天——selenium动态页面抓取

今天只是记录一下新看的内容,主要是有关selenium动态页面抓取的。

python+scrapy+selenium爬虫

https://blog.csdn.net/uselym/article/details/52525025

from scrapy.linkextractors import LinkExtractor

link = LinkExtractor(restrict_xpaths=’//ul[@class=”cont_xiaoqu”]/li’,allow=’re表达式’)

挑选符合条件的Link,然后可以进行处理如:content = link.extract_links(response)

上面的方法跟response方法比起来,差不多,类似response.xpath

好处是:写一次,下面可以瞬间多次调用。避免重复

这边还写到了parse里面另一种抓取内容方法:

sel = scrapy.Selector(response)

item = sel.xpath(self._x_query[‘item’]).extract()

哎哟喂,这样不是也可以调用多次?

好了,说一下好处吧,https://baijiahao.baidu.com/s?id=1582633570450116180&wfr=spider&for=pc真正的好处主要是提取和筛选链接。对网页里面所有的链接进行筛选并提取,这样的话你就不用去搞个什么linklist,然后再for循环筛选了。挺厉害的,之后用一用吧。

随后有个知乎登陆,虽然有点过时,但是里面有个思想比较厉害:

defparse(self, response):        return scrapy.Request(url=self.start_urls[0], cookies=self.get_cookies(), callback=self.after_login)

然后把getcookies和afterlogin写在spider文件里面,这样有什么好处?省时省力啊

这样你就可以定制化了,写个tool,然后在不同的包,然后import方法,可以直接调用

小白学习使用 Python + Scrapy 爬取动态网页

https://www.jianshu.com/p/f8606dda4d8c

driver.find_by…..一般找出来的是个webelement或者webelements,一般处理有两种方法:

WebElement.text返回文本内容

WebElement.getattribute(href)获取attribute value

[Python爬虫]Scrapy配合Selenium和PhantomJS爬取动态网页

https://blog.csdn.net/Julkot/article/details/77312116

一般init初始化重写的时候,先是继承参数super(YourSpiderName, self).__init__(*args, **kwargs),然后一般针对动态网页有个self.driver,看具体情况可能有allow_domain和start_url,name一般在外面。

init和start_request方法有什么不一样啊?嗯,,,想一下。startrequest里面一般用来生成start_urls的。

源码:for url in self.start_urls:

        yield self.make_requests_from_url(url)

或者变成yield scrapy.Request(url, self.parse)

start_request方法必须返回一个可迭代的第一个请求来抓取这个爬虫。

但是再init里面也可以生成start_urls。嗯,,,我想一下,,,讲道理应该是说,,可以轮换着提request,那样应该会比较慢一点。好一点。

webdriver的一些参数:

self.driver = webdriver.PhantomJS(executable_path=PHANTOMJS_PATH, service_args=[“–ssl-protocol=any”, “–ignore-ssl-errors=true”, “–load-images=false”, “–disk-cache=true”])。 其中

–ssl-protocol=any, –ignore-ssl-errors=true用来设置ssl的

–load-images=false设置了让PhantomJS不加载图片,有利于提高PhantomJS的速度

–disk-cache=true 启用本地磁盘缓存,同样有利于提高提高PhantomJS的速度

from selenium.webdriver.support.ui import WebDriverWaitfrom selenium.webdriver.support import expected_conditions as EC

wait.until(EC.visibility_of_element_located((By.CLASS_NAME, ‘select_hide’)))

Scrapy+PhantomJS+Selenium动态爬虫

https://blog.csdn.net/qq_30242609/article/details/70859891

如果需要phantomjs对特定的页面进行处理,需要在request里面写request.meta[‘PhantomJS’] = True

然后在download的middleware里面加入:

defprocess_request(cls, request, spider):        if request.meta.has_key(‘PhantomJS’):

如何在middleware里面写js函数,滚动到底端:然后每一次都执行

js = “””

function scrollToBottom() {

  var Height = document.body.clientHeight,  //文本高度        screenHeight = window.innerHeight,  //屏幕高度        INTERVAL = 100,  // 滚动动作之间的间隔时间        delta = 500,  //每次滚动距离        curScrollTop = 0;    //当前window.scrollTop 值    var scroll = function(){        curScrollTop = document.body.scrollTop;

        window.scrollTo(0,curScrollTop + delta);

    };

    var timer = setInterval(function(){        var curHeight = curScrollTop + screenHeight;

        if (curHeight >= Height){  //滚动到页面底部时,结束滚动            clearInterval(timer);

        }

        scroll();

    }, INTERVAL)}

scrollToBottom()

“””classPhantomJSMiddleware(object):    @classmethod    defprocess_request(cls, request, spider):        if request.meta.has_key(‘PhantomJS’):

            driver = webdriver.PhantomJS()

            driver.get(request.url)

            driver.execute_script(js) 

            time.sleep(1)  # 等待JS执行            content = driver.page_source.encode(‘utf-8’)

            driver.quit() 

            return HtmlResponse(request.url, encoding=’utf-8′,

Scrapy实战9动态设置ip代理从数据库中随机获取一个可用的ip

https://www.cnblogs.com/huwei934/p/7150795.html

这个主要写在ip爬虫里面。

代理ip网站

https://www.jianshu.com/p/93fd64a2747b

纯真

66免费代理网#推荐

西刺免费代理IP

酷伯伯HTTP代理

快代理

proxy360.cn

站大爷

Free Proxy List

年少#不稳定

全网代理IP

IP海

每日代理#渣渣

360代理IP

流年免费HTTP代理IP 24小时自助提取系统#推荐

云代理

秘密代理IP#渣渣

迷惘网络IP代理

敲代码 免费代理IP网#不稳定

代理IP检测平台,100免费代理IP

瑶瑶代理IP

米扑代理

httpdaili

蚂蚁代理

风云代理IP#不稳定

开心代理

讯代理

急速IP#渣渣

scrapy爬虫注意点(1)—— scrapy.FormRequest中formdata参数

https://blog.csdn.net/zwq912318834/article/details/78292536

利用scrapy FromRequest方法可以向网站提交表单数据。

# header信息unicornHeader = {

    ‘Host’: ‘www.example.com’,

    ‘Referer’: ‘http://www.example.com/’,

}# 表单需要提交的数据myFormData = {‘name’: ‘John Doe’, ‘age’: ’27’}# 自定义信息,向下层响应(response)传递下去customerData = {‘key1’: ‘value1’, ‘key2’: ‘value2’}yield scrapy.FormRequest(url = “http://www.example.com/post/action”,

                        headers = unicornHeader,

                        method = ‘POST’,            # GET or POST                        formdata = myFormData,      # 表单提交的数据                        meta = customerData,      # 自定义,向response传递数据                        callback = self.after_post,

                        errback = self.error_handle,

                        # 如果需要多次提交表单,且url一样,那么就必须加此参数dont_filter,防止被当成重复网页过滤掉了                        dont_filter = True   

                        )

scrapy第一次请求方式的重写

https://blog.csdn.net/weixin_41601173/article/details/80061139

什么时候重写startreques?

当起始请求需要设置header,cookie,data的时候,这个完美了

如何设置:

携带head和cookies

def start_requests(self):

        start_url = ‘要请求的链接’

        headers = {}

        cookies = {}

        yield scrapy.Request(url=start_url, headers=headers,callback=self.parse,cookies=cookies)

携带表单:

def start_requests(self):

        login_url = ‘要请求的链接’

        # 发送post请求

        data = {}

        yield scrapy.FormRequest(url=login_url,formdata=data,callback=self.after_login)

scrapy.FormRequest.from_response方法可以从响应response中自动提取表单POST地址,例如处理登录,需要先返回登录页面,再填充表单,然后提交

# 自动提取表单post地址    

    yield scrapy.FormRequest.from_response(

        response,#比如你点击后弹出response,就可以在这儿提交表单啊,牛皮

        headers=self.header,

        formdata=data,

        callback=self.after_login,#这边callback一下处理函数

    )

设置代理与随机选择请求头

request.meta[‘proxy’] = ‘http://’ + ‘代理IP’

轻松自动化—selenium-webdriver(python) (六)

https://www.cnblogs.com/fnng/p/3202299.html

这个网站侧边栏也很厉害,讲了selenium的一些基本用法,text,submit,get_attribute等最基本的,还有其他复杂的。

错误

[<twisted.python.failure.Failure <class ‘OpenSSL.SSL.Error’>>]

一般是useragent或者ip有错误,检查一下ip请求是不是需要https格式

Scrapy阅读源码分析<二>

https://blog.csdn.net/weixin_37947156/article/details/74436333

scrapy源码中的entry_points={

‘console_scripts’: [‘scrapy = scrapy.cmdline:execute’]

}一行指定了scrapy 的执行路径是cmdline中的excute方法。再看excute这个方法的源码,大概包含以下几个部分:

主要看出来的有几个点:一是scrapy.cfg文件很重要,是读取文件配置/生成setting的主要方法。第二是scrapy最终生成的是一个crawlerprocess实例。所以看懂scrapy一定要看懂crawler。

生成crawlerproces之后,运行的是cmdline的run方法,所以,假如运行的是scrapy crawl <spider name> 那么,运行的就是command/crawl.py函数。里面的run方法:

这个样字,好嘞,run方法中调用了CrawlerProcess实例的crawl和start,crawl读取了配置,start负责启动,然后这样整个爬虫程序就会运行起来了。

crawlprocess调用了crawlrunner的配置,初始化的时候调用了_get_spider_loader方法,默认配置文件中的spider_loader配置是spiderloader.SpiderLoader。爬虫加载器会加载所有的爬虫脚本,最后生成一个{spider_name: spider_cls}的字典。CrawlerProcess初始化完之后,调用crawl方法。这个过程会创建Cralwer实例,然后调用它的crawl方法。

。然后正式开始爬虫,初始化引擎,调用startrequest方法:

然后再调用start方法:

可以看出来,里面声明了一个reactor,这玩意儿是啥?稍微解释:它是Twisted模块的事件管理器,只要把需要执行的事件方法注册到reactor中,然后调用它的run方法,它就会帮你执行注册好的事件方法,如果遇到网络IO等待,它会自动帮你切换可执行的事件方法,非常高效。所以,scrapy实质上以来twisted,安装的时候也会依赖到这个包。你可以把它想象成一个线程池,只是采用注册回调的方式来执行事件。

还有,上面配置文件中,读取到了defaultsetting,非常重要,在:scrapy\settings\default_settings.py下。看源码可以知道,里面规定了好多的handler:

好多的默认middleware:

这个就厉害了,包括什么useragent啊,ajax啊,cookies啊,http代理啊之类的,都是默认的,超厉害。

再有,包括很多extension,这玩意儿是啥?

解释一下啊:Scrapy API的主要入口是 Crawler 的实例对象, 通过类方法 from_crawler 将它传递给扩展(extensions),详细解释参见这里。扩展(extensions)和中间件(middlewares)使用settings用来访问Scrapy的配置。

再有包括文件写入导出操作:

以及一些基本的middleware的源头:

这个就很厉害了,解决了源码中大部分的middleware以及其他代码。6666的飞起来。

超级干货 :一文读懂网络爬虫

http://www.sohu.com/a/194853807_197042

先大致看一下这个图,涉及到的东西有存储,分布式,异步,框架,提取,请求,robot协议,网页解析,技巧。我已经搞定的是:mysql存储,分布式是自带的,异步是自带的,提取用xpath或者css,请求是自带的,解析没有,表单,模拟登陆,验证码,代理都已经搞定。

很牛皮的个网页啊!!!讲的非常详细,有关爬虫的相关知识。可以多看几遍有时间。

需要看的是,scrapy异步怎么实现的,分布式怎么实现的。

好,来搜一下,scrapy的异步机制和分布式的实现:

首先说异步:所谓异步,就是你请求过快,biubiubiu请求,网页不一定biubiubiu回应,所以,这就造成网络的下载速度和数据库的I/O速度是不一样的,所以有可能会发生下载快,但是写入数据库速度慢,造成线程的堵塞;关于堵塞和非堵塞,同步和异步的关系。如何实现异步?主要就是再写入的时候,假如dbpool:

#创建初始化函数,当通过此类创建对象时首先被调用的方法 7    def __init__(self,dbpool): 8        self.dbpool = dbpool

然后再:

dbpool = adbapi.ConnectionPool(“MySQLdb”,dbparms)

然后,在process_item的时候:

def process_item(self,item,spider):31        #使用Twisted异步的将Item数据插入数据库32        query = self.dbpool.runInteraction(self.do_insert,item)33        query.addErrback(self.handle_error,item,spider)#这里不往下传入item,spider,handle_error则不需接受,item,spider)

实现主要是基于twisted的from twisted.enterprise import adbapi

    原文作者:沉默百年的猴
    原文地址: https://www.jianshu.com/p/a23af5e126a5
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞