Scrapy抓取百度搜索结果页排名

日期:2020-10-15 类型:产品中心

把握多少常识,就能抓住多少时机。“常识”来历于“信息”的提炼,而“信息”来历于“数据”的分析。从“数据”→“信息”→“常识”→“智慧”是一步步转化而来。

想从互联网领域中学习什么东西,不同于校园,老师可以直接给予学生现成的常识。互联网高速开展、不易猜测的特性,导致大部分信息仍处于未知的状态,没有多少人会通知你有什么信息、有什么常识。很多信息还躺在一坨坨数据中等候被分析出来。

所以我觉得,在互联网行业中,数据获取与分析是好像交流表达、时间管理一样的通用型技能,是可以不受职能控制而进行转移。

数据可以通过交换、购买、API等方式来获得,但假如其别人都没有,那就只能自己去找数据,然后分析出信息,提炼出常识。

举个例子,早年为了分析排在百度官网的网页都有什么一同特征,自己指定了几个可能影响排名的因素:网页巨细、下载速度、网页链接数量、正文字数、url的目录层级、query在正文的呈现次数、query分词后的词项在正文中的呈现次数、query在title中的呈现次数等十几个指标,拿了5000个长尾词跑百度查找成果,把前5页呈现的网页悉数抓下来,跑出前面指定的十几个指标对应的数据,然后分析所处不同分页的网页(每个分页个5万个样本),在指标上有什么显着的规律。

以上是获取数据,对数据分析后发现:

1、排在第一页的成果,均匀正文字数500,第二页~第五页的成果依次递减;

2、排在第一页的成果,均匀网页包含的链接数量130,第二页~第五页的成果依次递增;

3、其他指标,在所有分页中均无显着动摇。

 

以上是信息,对信息进行提炼,形成常识:

1、网页正文字数和网页包含的链接会影响长尾词的排名

2、掩盖长尾词的页面,保证正文字数控制在500字以上,网页中包含的链接控制在130以下,会提高网页呈现在百度官网的概率

 

当然,真实的网页排序因素远比这个杂乱多得多,除了以上两点肯定还要同时满足多个条件才干呈现在官网。

另外,还需留意获取的数据的可靠性和公正性,可靠性是数据能不能推导出正确的结论;公正性是这个数据是不是公平的。

仍是上面的例子,假如换成5000个热词,那核算出来的成果就不可靠也不公正。因为百度是一个商业查找引擎,而在长尾词上,百度会相对不那么商业。

做流量的,很大都据得需要自己去抓,抓取就要用到爬虫。花了几地利间体验了下python的Scrapy,感觉不错,是一个高性能、易上手、强健安稳、可高度定制、可分布的爬虫框架。

作为一个成熟的爬虫框架,肯定比自己现手写一个爬虫要来的快的多,而相比火车头,它能完成火车头完成不了的功用,比如上面说的例子。

下面是Scrapy的使用小记

项目构成:

scrapy.cfg:项目配置文件
items.py:存放抓取数据的
pipelines.py:处理抓取数据的
settings.py:爬虫配置文件,有现成的API,可添加各种防ban策略
middlewares.py:中心件
dmoz_spider.py:爬虫程序

参照官方文档和Google写了个抓取百度排名的程序,上手后,在配置速度比火车头还要快一些。

考虑百度封闭爬虫比较严,需要一些防屏蔽策略,选用如下方法完成:

1、轮换出口IP

用scrapinghub提供的代理,因为是国外的IP,所以拜访百度比国内要慢一些,可是提供的代理很安稳,便利配置,且免费,貌似没有使用次数的限制。

在sittings.py中添加:

'''crawlera账号、密码'''
CRAWLERA_ENABLED = True
CRAWLERA_USER = '账号'
CRAWLERA_PASS = '密码'
'''下载中心件设置'''
DOWNLOADER_MIDDLEWARES = {
'scrapy_crawlera.CrawleraMiddleware': 600
}

 

2、轮换UA

在sittings.py添加:


USER_AGENTS = [   "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; AcooBrowser; .NET CLR 1.1.4322; .NET CLR 2.0.50727)",   "Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; fr) Presto/2.9.168 Version/11.52",  .......  ]  '''下载中心件设置'''  DOWNLOADER_MIDDLEWARES = {   'tutorial.middlewares.RandomUserAgent': 1,  } 
class RandomUserAgent(object):"""Randomly rotate user agents based on a list of predefined ones"""def __init__(self, agents):   self.agents = ;from_crawler(cls, crawler):   return cls(crawler.settings.getlist('USER_AGENTS'))def process_request(self, request, spider):   #print "**************************" + random.choice(self.agents)   request.headers.setdefault('User-Agent', random.choice(self.agents)) 
 cookie_list = [   'cookie1', #自己从不同浏览器中获取cookie在添加到这   'cookie2',   ......  ]   cookie = random.choice(cookie_list)   return cookie    '''设置默认request headers'''    DEFAULT_REQUEST_HEADERS = { 'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',   'Accept-Encoding':'gzip, deflate, sdch',   'Accept-Language':'zh-CN,zh;q=0.8,en;q=0.6',   'Cache-Control':'max-age=0',   'Connection':'keep-alive',   'Host':'',   'RA-Sid':'7739A-030243-3adabf-48f828',   'RA-Ver':'3.0.7',   'Upgrade-Insecure-Requests':'1',   'Cookie':'%s' % getCookie()  } 
'''启用AutoThrottle扩展,默认为False'''  AUTOTHROTTLE_ENABLED = False    '''设置下载超时'''  DOWNLOAD_TIMEOUT = 10    '''降低log级别,撤销注释则输出抓取概况'''  LOG_LEVEL = 'INFO' 
 name = "dmoz"   allowed_domains = [""]     # start_urls = ['s?q= tn=baidulocal ct=2097152 si= ie=utf-8 cl=3 wd=seo%E5%9F%B9%E8%AE%AD']     start_urls = []   for word in open('/Users/sunjian/Desktop/tutorial/tutorial/spiders/word.txt'):   word = word.strip()   url = 's?q= tn=baidulocal ct=2097152 si= ie=utf-8 cl=3 wd=%s' % urllib.quote(word)   start_urls.append(url)     def __get_url_query(self, url):   m = re.search("wd=(.*)", url).group(1)   return m     def parse(self,response):   n = 0     for sel in response.xpath('//td[@ ]'):     query = urllib.unquote(self.__get_url_query(response.url))     item = DmozItem()     title = re.sub(' [^ ]*? ','',sel.xpath('.//a/font[@size="3"]').extract()[0])   lading = sel.xpath('.//a[1]/@href').extract()[0]   time = sel.xpath('.//font[@color="#008000"]/text()').re('(\d{4}-\d{1,2}-\d{1,2})')[0]   size = sel.xpath('.//font[@color="#008000"]/text()').re('(\d+K)')[0]     n += 1     item['rank'] = n   item['title'] = title.encode('utf8')   item['lading'] = lading.encode('utf8')   item['time'] = time.encode('utf8')   item['size'] = size.encode('utf8')   item['query'] = query     yield item 
class MySQLTutorialPipeline(object):   def __init__(self, dbpool):   self.dbpool = dbpool     @classmethod   def from_settings(cls, settings):   dbargs = dict(   host=settings['MYSQL_HOST'],   db=settings['MYSQL_DBNAME'],   user=settings['MYSQL_USER'],   passwd=settings['MYSQL_PASSWD'],   charset='utf8',   cursorclass = MySQLdb.cursors.DictCursor,   use_unicode= True,   )   dbpool = adbapi.ConnectionPool('MySQLdb', **dbargs)   return cls(dbpool)     #pipeline默认调用   def process_item(self, item, spider):   d = self.dbpool.runInteraction(self._do_upinsert, item, spider)   d.addErrback(self._handle_error, item, spider)   d.addBoth(lambda _: item)   return d     #将每行更新或写入数据库中   def _do_upinsert(self, conn, item, spider):   conn.execute(""" INSERT INTO baidu_pc_rank VALUES ('%s','%s','%s','%s','%s','%s') """ % (item['rank'],item['title'],item['lading'],item['time'],item['size'],item['query']))   #获取url的md5编码   def _get_linkmd5id(self, item):   #url进行md5处理,为防止重复采集设计   return md5(item['address']).hexdigest()   #异常处理   def _handle_error(self, failue, item, spider):   log.err(failure) 
ITEM_PIPELINES = {  'tutorial.pipelines.MySQLTutorialPipeline': 400,  } 
是一家从事SMT设备的代理,设计、出售及效劳的设备商,深圳三本建立的宗旨是为用户提供先进的设备和技能,既合乎用户现在出产需要且兼顾将来科技开展。此外,本司对用户提供的完善技能支撑,亦是本司成功的重点。