【Python真的很强大】使用yield优雅抓取网页分页数据

本文介绍了一种使用Python优雅地抓取分页数据的方法,包括解析页面内容和获取下一页URL的技术细节。

使用yield优雅抓取网页分页数据

在使用Python来抓取网页数据的时候,常常碰到分页数据,其中部分下一页按钮已经有具体的链接地址,而另外的可能是javascript来处理分页的。这要求同时能解析页面内容,又要采集下一页的url。怎样优雅用python写这样的代码呢?或者说怎样更pythonic?

下面分别给出部分代码实例

 

 

def get_next_page(obj):
                '''get next page content from a url or another content '''
                error_occurred = False
                for retry2 in xrange(3):
                    try:
                        if isinstance(obj, (basestring, unicode)):
                            resp = curr_session.get(obj, timeout=TIMEOUT, headers=headers,
                                                    cookies=cookies, allow_redirects=True)
                            content = resp.content
                            save_html_content(obj, content)
                            error_occurred = False
                        else:
                            content = obj
                        soup = BeautifulSoup(content, features='html5lib', from_encoding="utf8")
                        e_next_page = soup.find('a', text="下頁")
                        break
                    except:
                        error_occurred = True
                        time.sleep(2)
                if error_occurred:
                    yield content
                    return
                if e_next_page:
                    next_url = "http://www.etnet.com.hk" + e_next_page.get('href')
                    time.sleep(2)
                    yield content
                    for i in get_next_page(next_url):
                        yield i
                else:
                    yield content

 

def get_next_page(obj, page=1):
        '''get next page content from a url or another content '''
        error_occurred = False
        for retry2 in xrange(3):
            try:
                if isinstance(obj, (basestring, unicode)):
                    resp = curr_session.get(obj, timeout=TIMEOUT, headers=headers,
                                            cookies=cookies, allow_redirects=True)
                    content = resp.content
                    save_html_content(obj, content)
                    hrefs = re.findall('industrysymbol=.*&market_id=[^;]+', content)
                    if page == 1 and (not "sh=" in obj) and hrefs:
                        reset_url = ("http://www.aastocks.com/tc/cnhk/market/industry"
                                     "/sector-industry-details.aspx?%s&page=1" % \
                            (hrefs[0].replace('sh=1', 'sh=0').replace('&page=', '') \
                             .replace("'", '').split()[0]))
                        for next_page in get_next_page(reset_url):
                            yield next_page
                        return
                    error_occurred = False
                else:
                    content = obj
                soup = BeautifulSoup(content, features='html5lib', from_encoding="utf8")
                e_next_page = soup.find('td', text="下一頁 ")
                break
            except:
                error_occurred = True
                LOG.error(traceback.format_exc())
                time.sleep(2)
        if error_occurred:
            yield content
            return
        if e_next_page:
            hrefs = re.findall('industrysymbol=.*&market_id=[^;]+', content)
            if hrefs:
                next_url = ("http://www.aastocks.com/tc/cnhk/market/industry/sector-industry"
                            "-details.aspx?%s&page=%d" % \
                            (hrefs[0].replace('sh=1', 'sh=0') \
                             .replace('&page=', '').replace("'", '').split()[0], page+1))
            time.sleep(2)
            yield content
            for next_page in get_next_page(next_url, page+1):
                yield next_page
        else:
            yield content

 

 

for curr_href in e_href:
                retry_interval = random.randint(MIN_INTERVAL_SECONDS_FOR_RETRIEVING,
                                                MAX_INTERVAL_SECONDS_FOR_RETRIEVING)
                time.sleep(retry_interval)
                contents = get_next_page(curr_href)
                for content in contents:
                    get_page_data(content)

 

### 使用 Scrapy 实现网页数据抓取 Scrapy 是一个功能强大且灵活的 Python 爬虫框架,适用于多种场景的数据抓取任务[^3]。以下是基于 Scrapy 的基本教程以及示例代码。 #### 创建 Scrapy 项目 首先需要安装 Scrapy 库并创建一个新的 Scrapy 项目: ```bash pip install scrapy scrapy startproject myspider ``` 上述命令会生成名为 `myspider` 的目录结构,其中包含了爬虫所需的配置文件和模板。 #### 配置 Spider 文件 进入项目的 spiders 子目录下新建一个 spider 脚本,例如命名为 `example_spider.py`: ```python import scrapy class ExampleSpider(scrapy.Spider): name = 'example' # 唯一标识符 allowed_domains = ['example.com'] # 允许访问的域名列表 start_urls = ['https://www.example.com/'] # 初始请求地址 def parse(self, response): # 提取所需字段 title = response.css('title::text').get() yield {'title': title} # 如果有分页或其他链接,则继续发送请求 next_page = response.css('a.next-page::attr(href)').get() if next_page is not None: yield response.follow(next_page, self.parse) ``` 这段代码定义了一个基础爬虫类继承自 `scrapy.Spider` 并实现了解析方法 `parse()` 来处理 HTML 数据[^1]。 #### 设置定时任务 为了使爬虫能够按照设定的时间间隔运行,可以通过 Linux 的 cron 或 Windows 的计划任务来调用脚本执行;或者利用 Celery 和 Redis 组合实现分布式调度机制[^2]。这里提供一种简单的方式——借助 APScheduler 库完成本地定时触发: ```python from apscheduler.schedulers.blocking import BlockingScheduler from scrapy.crawler import CrawlerProcess from myspider.spiders.example_spider import ExampleSpider def run_spider(): process = CrawlerProcess({ 'USER_AGENT': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)', 'FEED_FORMAT': 'json', 'FEED_URI': 'output.json' }) process.crawl(ExampleSpider) process.start() if __name__ == "__main__": scheduler = BlockingScheduler() scheduler.add_job(run_spider, 'interval', days=1) # 每隔一天运行一次 scheduler.start() ``` 以上展示了如何设置每日一次的任务安排。 #### 运行与调试 最后,在终端启动该程序即可按预定时间表自动获取目标网站上的最新资料。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值