安装了python3.8但是没有pip
在ubuntu上从Python 3.4版和2.7.9版开始,总是可以使用ensurepip
模块来引导启动pip
,具体如下:
1 2 3 4 5 6 7 8
| C:\Users\Administrator>python -m ensurepip Looking in links: c:\Users\ADMINI~1\AppData\Local\Temp\tmpcempbgwg Processing c:\users\administrator\appdata\local\temp\tmpcempbgwg\setuptools-47.1 .0-py3-none-any.whl Processing c:\users\administrator\appdata\local\temp\tmpcempbgwg\pip-20.1.1-py2. py3-none-any.whl Installing collected packages: setuptools, pip Successfully installed pip-20.1.1 setuptools-47.1.0
|
爬虫https,不安全的问题
Python2/3 解决访问Https时不受信任SSL证书问题
1
| ssl._create_default_context = ssl._create_unverified_context
|
安装scrapy遇到错误
1 2 3 4 5 6 7 8 9
| Downloading https://pypi.tuna.tsinghua.edu.cn/packages/f2/16/3eb9c66a7bfb5220c7bcbaaac33d359fe8a157b028959cd210983749b2e0/Twisted-21.2.0-py3-none-any.whl (3.1 MB) |███████████████████████████████▌| 3.0 MB 262 kB/s eta 0:00:01 ERROR: THESE PACKAGES DO NOT MATCH THE HASHES FROM THE REQUIREMENTS FILE. If you have updated the package versions, please update the hashes. Otherwise, examine the p ackage contents carefully; someone may have tampered with them. Twisted[http2]>=17.9.0 from https://pypi.tuna.tsinghua.edu.cn/packages/f2/16/3eb9c66a7bfb5220c7bcbaaac33d359fe8a157b028959cd210983749b2e0/Twisted-21.2.0-py3-none- any.whl#sha256=aab38085ea6cda5b378b519a0ec99986874921ee8881318626b0a3414bb2631e (from scrapy): Expected sha256 aab38085ea6cda5b378b519a0ec99986874921ee8881318626b0a3414bb2631e Got c9b2f7ffbc1fb53011ba7c6500d784a78ef9e1f8274fa472eebc1eab930b216b
|
换个pip的源解决了
1
| (venv) C:\Users\Administrator\Desktop\爬虫项目文件夹\scrapyDemo>pip3 install scrapy -i https://pypi.mirrors.ustc.edu.cn/simple
|
使用python2 环境安装scrapy使用的时候报错from contextlib import suppress
原因
因为我之前安装过python3,我的环境中的queuelib
的版本为1.6.0,是最新版本,但是这个包刚刚好再1.6.0取消了对python2的支持。
解决办法
下载queuelib
1.5.0的whl,安装一下。
下载地址https://www.cnblogs.com/klb561/p/9271322.html
No module named ‘scrapy.xlib’
1 2 3 4
| from scrapy.xlib.pydispatch import dispatcher
from pydispatch import dispatcher
|
scrapy 数据保存json文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
|
from scrapy.exporters import JsonItemExporter import time
class SpiderPipeline(object): def __init__(self): time_str = str(time.strftime('%Y_%m_%d_%H_%M_%S',time.localtime(time.time()))) print time_str self.json_file = open(time_str + '_data.json', 'wb') self.json_exporter = JsonItemExporter(self.json_file, ensure_ascii=False, encoding='UTF-8') self.json_exporter.start_exporting()
def process_item(self, item, spider): self.json_exporter.export_item(item) return item
def close_spider(self, spider): self.json_exporter.finish_exporting() self.json_file.close()
|
1 2 3 4
| ITEM_PIPELINES = { 'NsmcSpider.pipelines.SpiderPipeline': 300, }
|
其他方法
命令行执行
scrapy crawl spider -o result.json -t json
crawl spider -o result.json -s FEED_EXPORT_ENCODING=UTF-8
爬虫速度慢或者速度不稳定的另外一种解决办法
把cookie给禁掉
1
| custom_settings = {"COOKIES_ENABLED":False}
|
使用scrapy.http.Request
数据不全的问题
记得加上报文头
1 2 3 4
| headers = { "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36", "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", }
|
出现错误Filtered offsite request to
原因:allowed_domains
和实际采集的网页有出入
解决办法:
1 2 3
| yield Request(url=home, method='get', headers=self.headers,dont_filter=True, meta={"channel": response.meta["channel"], }, callback=self.parse_link)
|
加上dont_filter=True
或者 将allowed_domains
的内容改一下,改成一级域名,能够和后面的匹配的上。
报错Filtered duplicate request: GET xxx - no more duplicates
原因: 爬取的url重复了,所以RedisSpider模块默认会记录爬过的url,会把后面出现以前爬过的url去掉,导致重新开启程序爬取之前爬过的url,都被去除掉后就爬不到东西。
解决办法:
加上dont_filter=True
scrapy有一个基于链接的去重,加上dont_filter=True
可以完整的采集,去重可以放到入库的时候再处理。
ValueError: check_hostname requires server_hostname
可能是开了代理
进行请求的时候使用urlencode
进行转码报错TypeError: not a valid non-string sequence or mapping object
使用quote_plus
禁止重定向
1 2 3 4
| yield Request(url=final, method='get', headers=self.headers,cookies=cookie, meta={"channel": response.meta["channel"], "start_hash": response.meta['start_hash'], "dont_redirect":True,'handle_httpstatus_list': [302]}, callback=self.parse_item)
|