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定位时就失效了。这个问题很常见,大体思路是这样的。
- 创建一个包含所有字段的dict:
data = {}.fromkeys(('url', 'price', 'address'))
- 然后根据网页中是否有字段来取值,例如,有'url'就取对应的value,没有则为空
- 这样就可以完美解决匹配不全问题
Scrapy 相关
文件编写
逻辑文件和解析部分分开写,匹配文件目录是utils/parse/
,爬虫文件目录是spiders/
Scrapy 中文乱码
在 setting
文件中设置:FEED_EXPORT_ENCODING = 'utf-8'
Scrapy 使用Mongo
pipelines.py
- 首先我们要从settings文件中读取数据的地址、端口、数据库名称。
- 拿到数据库的基本信息后进行连接。
- 将数据写入数据库(update制定唯一键)
- 关闭数据库
注意:只有打开和关闭是只执行一次,而写入操作会根据具体的写入次数而定。 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
,使用 Redis
的 set
类型(去重种子链接)
安装
超时问题
自定义超时时间
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
,查看目录,会显示相应的类和函数
激活码
- http://idea.liyang.io
- 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
好了,今天先写这点,以后再补上。
- nginx访问报错:Too many open files accept:
- iptables之NAT端口转发设置
- 使用Combres 库 ASP.NET 网站优化
- jQuery和asp.net mvc相关资源链接
- JavaScriptSerializer 序列化json 时间格式
- Nginx反向代理+负载均衡简单实现(https方式)
- 在网页中给Flash加上超级链接
- ASP.NET MVC HandleErrorAttribute 和 远程链接
- javascript实现数字转大写金额的函数
- 如何在GridView的Footer内显示总计?
- 自定义WCF的配置文件
- Centos中动态扩容lvm逻辑卷的操作记录
- Visual Round Trip Analyzer
- ASP.NET可以在Windows Server 2008 R2 Server Core上运行
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Android使用DrawerLayout实现侧滑菜单效果
- android语音即时通讯之录音、播放功能实现代码
- win10 装centos7 虚拟机
- 怎样给centos系统扩展磁盘分区的实现方法
- android系统分享的自定义功能的示例代码
- Linux centOS安装JDK和Tomcat的教程
- Android ContentProvider实现获取手机联系人功能
- Centos 安装 PHP7.4 和 Nginx的操作方法
- vsftpd用户禁止ssh登陆的实现方法
- Android实现EditText图文混合插入上传功能
- Android实现红包雨动画效果
- 手把手教你启用Win10的Linux子系统(图文超详细)
- Android onCreateOptionsMenu的使用方法总结
- android截图事件监听的原理与实现
- 我常用的一些linux命令小结