首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一个通用爬虫思路(Python3)

一个通用爬虫思路(Python3)

作者头像
小歪
发布2018-04-04 14:34:38
5650
发布2018-04-04 14:34:38
举报

我们是谁?

萌新!

我们要什么?

学习爬虫!

什么时候要?

天天要!

其实一个爬虫无非就三步:下载数据、解析数据、保存数

本文提供一个代码示例,分别展示这三步骤

1

下载数据

def dowmlpad(url, user_agent='wswp', proxy=None, num_retries=2, timeout=5):
    """
    # 支持500错误重试
    # 设定用户代理 user_agent
    # 支持ip代理
    """
    print('DownloadURL:',url)

    #配置用户代理
    headers = {'User-agent':user_agent}
    request = urllib.request.Request(url, headers=headers)   
   
    #配置
    opener = urllib.request.build_opener()    
    
    #判断是否代理
    if proxy:
        proxy_params = {urllib.parse.urlparse(url).scheme:proxy}
        opener.add_handler(urllib.request.ProxyHandler(proxy_params))    
    try:
        html = opener.open(request, timeout=timeout).read()    
    except urllib.request.URLError as e:
        print('Download error:',e.reason)
        html = None
        if num_retries > 0:            
             if hasattr(e,'code') and 500 <= e.code <600:
                html = dowmlpad(url, user_agent, num_retries-1)    
        except Exception as e:
        print('error :',e)
        html = None

    return html

2

解析数据

#编写爬取规则,获得数据

def scrape_callback(url,html):
    csslist = ['span[property = "v:itemreviewed"]', 'span.year', 'strong[property="v:average"]']    
    try:
        tree = lxml.html.fromstring(html)
        row = [tree.cssselect('{0}'.format(field))[0].text for field in csslist]

        print(url, row)    
    except Exception as e:
        print("ScrapeCallback error:",e)
    
"""
seed_url:种子url
link_regex: 提取链接的正则表达式
max_depath:提取链接的深度,默认为2爬虫到达第二场页面后不再提取链接 ,对于种子页面取出的链接页面,就是第二层,
scrape_callback:回掉函数
"""

def link_crawler(seed_url, link_regex, max_depath=2, scrape_callback=None):
    crawl_queue = [seed_url]  #配置爬取队列,其实就是一个存储url的列表
    #seen = set(crawl_queue)
    seens = {seed_url:1}

    # 循环直到队列为空退出
    while crawl_queue:
        url = crawl_queue.pop()  # 移除队列最后一个元素,并返回值
        html = dowmlpad(url)     # 根据url 下载页面
        depth = seens[url]       # 获得url深度
        print(depth)        #获取页面中的链接
        for link in get_links(html):            
            if depth != max_depath and re.search(link_regex,link):
                link = urllib.parse.urljoin(seed_url, link)     #组装规范链接

                #添加链接到爬取队列中
                if link not in seens:
                    seens[link] = depth+1
                    crawl_queue.append(link)        #如果处理回调函数存在,则进行回调处理
        if scrape_callback:
            scrape_callback(url, html)

3

保存数据

import csvclass ScrapeCallback:
    def __init__(self):
        self.writer = csv.writer(open('countries.csv','w'))
        self.fields = ('name','year','score')
        self.writer.writerow(self.fields)
    def __call__(self, url,html):
        csslist = ['span[property = "v:itemreviewed"]', 'span.year','strong[property="v:average"]']        
        try:
            tree = lxml.html.fromstring(html)
            row = [tree.cssselect('{0}'.format(field))[0].text for field in csslist]
            self.writer.writerow(row)
            print(url, row)        
        except Exception as e:\
            print("ScrapeCallback error:",e)

最后主函数

if __name__ == '__main__':    #测试
    send_url = "https://movie.douban.com/"

    link_regex = '(/subject/[\d]+/)' #获取链接的规则

    #使用类的方式来写,下面两个一样结果
    link_crawler(send_url,link_regex,max_depath=2, scrape_callback=ScrapeCallback())
    #link_crawler(send_url, link_regex, max_depath=2, scrape_callback=scrape_callback)

这里只是大致展示了框架,更详细的注释可以去zhangslob/Python-General-Spider

爬虫其实很简单,不要过于纠结方法,记住三步:下载数据、解析数据、保存数据

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-08-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Python爬虫与算法进阶 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档