Hi,这里是我的爬虫笔记

平时有个习惯,会把自己的笔记写在有道云里面,现在做个整理。会长期更新,因为我是BUG制造机。

解析

xpath提取所有节点文本

<div id="test3">我左青龙,<span id="tiger">右白虎,<ul>上朱雀,<li>下玄武。</li></ul>老牛在当中,</span>龙头在胸口。<div>

使用xpath的string(.)

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from scrapy.selector import Selector

text = '<div id="test3">我左青龙,<span id="tiger">右白虎,<ul>上朱雀,<li>下玄武。</li></ul>老牛在当中,</span>龙头在胸口。<div>'
s = Selector(text=text)
data = s.xpath('//div[@id="test3"]')
info = data.xpath('string(.)').extract()[0]
print(info)

# output: 我左青龙,右白虎,上朱雀,下玄武。老牛在当中,龙头在胸口。

如何解决详情页面元素改变

这个问题是这样产生的,在很多PC站,比如链家,这个页面有这些字段A,但是下个页面这个字段A没了,取而代之的是字段B,在xpath定位时就失效了。这个问题很常见,大体思路是这样的。

  1. 创建一个包含所有字段的dict: data = {}.fromkeys(('url', 'price', 'address'))
  2. 然后根据网页中是否有字段来取值,例如,有'url'就取对应的value,没有则为空
  3. 这样就可以完美解决匹配不全问题

Scrapy 相关

文件编写

逻辑文件和解析部分分开写,匹配文件目录是utils/parse/,爬虫文件目录是spiders/

Scrapy 中文乱码

setting 文件中设置:FEED_EXPORT_ENCODING = 'utf-8'

Scrapy 使用Mongo

pipelines.py

  1. 首先我们要从settings文件中读取数据的地址、端口、数据库名称。
  2. 拿到数据库的基本信息后进行连接。
  3. 将数据写入数据库(update制定唯一键)
  4. 关闭数据库

注意:只有打开和关闭是只执行一次,而写入操作会根据具体的写入次数而定。 Redis 无需关闭

import pymongo

class MongoDBPipeline(object):
    """
    1、连接数据库操作
    """
    def __init__(self,mongourl,mongoport,mongodb):
        '''
        初始化mongodb数据的url、端口号、数据库名称
        :param mongourl:
        :param mongoport:
        :param mongodb:
        '''
        self.mongourl = mongourl
        self.mongoport = mongoport
        self.mongodb = mongodb

    @classmethod
    def from_crawler(cls,crawler):
        """
        1、读取settings里面的mongodb数据的url、port、DB。
        :param crawler:
        :return:
        """
        return cls(
            mongourl = crawler.settings.get("MONGO_URL"),
            mongoport = crawler.settings.get("MONGO_PORT"),
            mongodb = crawler.settings.get("MONGO_DB")
        )

    def open_spider(self,spider):
        '''
        1、连接mongodb数据
        :param spider:
        :return:
        '''
        self.client = pymongo.MongoClient(self.mongourl,self.mongoport)
        self.db = self.client[self.mongodb]

    def process_item(self,item,spider):
        '''
        1、将数据写入数据库
        :param item:
        :param spider:
        :return:
        '''
        name = item.__class__.__name__
        # self.db[name].insert(dict(item))
        self.db['user'].update({'url_token':item['url_token']},{'$set':item},True)
        return item

    def close_spider(self,spider):
        '''
        1、关闭数据库连接
        :param spider:
        :return:
        '''
        self.client.close()

scrapy图片下载

import scrapy
from scrapy.pipelines.images import ImagesPipeline
from scrapy.exceptions import DropItem

class MyImagesPipeline(ImagesPipeline):

    def get_media_requests(self, item, info):
        for image_url in item['image_urls']:
            yield scrapy.Request(image_url)

    def item_completed(self, results, item, info):
        image_paths = [x['path'] for ok, x in results if ok]
        if not image_paths:
            raise DropItem("Item contains no images")
        item['image_paths'] = image_paths
        return item

scrapy 暂停爬虫

scrapy crawl somespider -s JOBDIR=crawls/somespider-1

scrapy_redis 分布式

使用队列与去重即可完成分布式需求,需要注意的是 Redis 格式,默认采用的是 list, 可以在 settings.py 文件中设置REDIS_START_URLS_AS_SET = True,使用 Redisset类型(去重种子链接)

安装

超时问题

自定义超时时间

sudo pip3 --default-timeout=100 install -U scrapy

或者 使用其他源

sudo pip3 install scrapy -i https://pypi.tuna.tsinghua.edu.cn/simple

权限问题

安装某模块时,报错:PermissionError: [WinError 5] 拒绝访问。: 'c:\\program files\\python35\\Lib\\sit e-packages\\lxml'

最简单方法:pip install --user lxml

Pycharm 相关

.gitignore 文件

安装插件: Preferences > Plugins > Browse repositories... > Search for ".ignore" > Install Plugin

然后就可以很方便的添加到 .gitignore

显示函数

点击 Show Members,查看目录,会显示相应的类和函数

激活码

  1. http://idea.liyang.io
  2. http://xidea.online

不要更到最新版本

数据

Mongo导出命令

λ mongoexport -d test -c set --type=csv -f name,age -o set.csv

λ mongoexport -h 10.10.10.11 -d test -c test --type=csv -f url,id,title -o data.csv

其他

requirements.txt 文件

小提示:使用 pigar 可以一键生成 requirements.txt 文件

Installation:pip install pigar

Usage:pigar

好了,今天先写这点,以后再补上。

原文发布于微信公众号 - Python爬虫与算法进阶(zhangslob)

原文发表时间:2018-03-25

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏用户3030674的专栏

GreenDao教程1

最近项目重构,涉及到了数据库和文件下载,发现GreenDao这个框架还是不错的。直接面向对象的,可以通过对对象的操作,实现数据的存储。

983
来自专栏一个爱瞎折腾的程序猿

asp.net core使用Swashbuckle.AspNetCore(swagger)生成接口文档

开局一张图,然后开始编,一些基本的asp.net core东西就不再赘述,本文只对Swashbuckle.AspNetCore的几个使用要点进行描述。

1361
来自专栏有趣的django

python爬虫人门(10)Scrapy框架之Downloader Middlewares

设置下载中间件(Downloader Middlewares)  下载中间件是处于引擎(crawler.engine)和下载器(crawler.engine.d...

3718
来自专栏张戈的专栏

服务器反爬虫攻略:Apache/Nginx/PHP禁止某些User Agent抓取网站

我们都知道网络上的爬虫非常多,有对网站收录有益的,比如百度蜘蛛(Baiduspider),也有不但不遵守 robots 规则对服务器造成压力,还不能为网站带来流...

5125
来自专栏菩提树下的杨过

Flash/Flex学习笔记(53):利用FMS快速创建一个文本聊天室

先来看客户端fla的构成: 第一帧:登录界面 ? 第一帧的代码: import flash.events.MouseEvent; import com.adob...

2029
来自专栏程序员的碎碎念

JS动态加载以及JavaScript void(0)的爬虫解决方案

对于使用JS动态加载, 或者将下一页地址隐藏为JavaScript void(0)的网站, 如何爬取我们要的信息呢?

1576
来自专栏java达人

ThreadLocal与Spring 事务管理

编写线程安全代码的关键是管理程序中的共享可变状态,除了通过synchronized加锁机制防止多个线程同时访问同一段数据外,还有一种方法就是通过ThreadLo...

22510
来自专栏前端大白专栏

关于ant-design表单问题

2494
来自专栏恒思考

一个人的app后端-parse的安装与使用

mkdir -p ~/mongo ~/mongo/db cd ./mongo/ docker run -p 27017:27017 -v ~/mongo/db:...

2183
来自专栏james大数据架构

资源等待类型sys.dm_os_wait_stats

动态管理视图  sys.dm_os_wait_stats  返回执行的线程所遇到的所有等待的相关信息。可以使用该聚合视图来诊断 SQL Server 以及特定查...

2127

扫码关注云+社区