大型分佈式爬蟲準備 scrapy + request

那些高手css

爬蟲好文html

而我避免這些問題的方式,控制檯清除全部定時

 var id = setInterval(function() {}, 0);
while (id--) clearInterval(id);

$(articleSelector).css('height', 'initial')
          $(articleSelector).removeClass('lock')
          $('#locker').css('display', 'none')

python 運行 js 腳本

pip install PyExecJS

eleme.js

function getParam(){
    return 'hello world!'
}


xxx.py 

import execjs

import os

os.environ["EXECJS_RUNTIME"] = "PhantomJS"
node = execjs.get()
file = 'eleme.js'
ctx = node.compile(open(file).read())
js_encode = 'getParam()'
params = ctx.eval(js_encode)
print(params)

python 包管理

virtualenv virtualwrapper pipenv pyenv --》 conda

步驟

1. pipenv shell
2. pip install scrapy
3. scrapy shell   # 能夠作 簡單調試
3. scrapy startproject videospider  # 生成 基本骨架
4. scrapy genspider jobbole  www.jobbole.com
5. 取巧 構造一個 main.py  用來在 IDE 裏調試

爬蟲中 url 去重

set 去重 是 很是佔用內存的
md5 信息摘要 算法 以後會省不少, 可是仍然不如 bitmap 方式

bitmap  會 很容易 形成 hash 衝突

bloom filter  這一種 能夠經過 hash 函數 減小 hash 衝突

簡而言之 言而簡之 urls --> set(urls) --> set(md5(url) s) --> bitmap( xxx ) --> bloom filter( multi_hash_func ( xxx ))

下面這個教程要看評論再說。。。坑哭了

https://blog.csdn.net/chenvast/article/details/79103288

爬取 cnblog 文章 練手

# 使用 pipenv 管理環境
mkdir spiders
cd spiders
pipenv install

pip install scrapy -i http://pypi.douban.com/simple --trusted-host pypi.douban.com

# 利用 模板生成 項目基本樣子 相似於 springboot
scrapy startproject ArticleSpider

# 爬取 二級域名下的 文章
cd  xxx\ArticleSpider\ArticleSpider\spiders\
scrapy genspider cnblog news.cnblogs.com

# 修改 settings.py 中 的 爬蟲配置 ROBOTSTXT_OBEY  爲 False
ROBOTSTXT_OBEY = False

# 打開 編輯自動生成的 spider/cnblog.py
# -*- coding: utf-8 -*-
import scrapy
import re
from ArticleSpider.items import ArticleItem
from ArticleSpider.utils.utils import get_md5
from scrapy.http import Request
from urllib import parse

class CnblogSpider(scrapy.Spider):
    name = 'cnblog'
    allowed_domains = ['news.cnblogs.com']
    start_urls = ['http://news.cnblogs.com/']

    def parse(self, response):
        news_selector_list = response.xpath('//div[@id="news_list"]/div[@class="news_block"]')
        for news_selector in news_selector_list:
            content = news_selector.xpath('div[@class="content"]')
            anchor = content.xpath('h2/a')
            article_url = anchor.xpath('@href').extract()[0]
            article_title = anchor.xpath("text()").extract()[0]
            article_front_image_url = content.xpath('div[@class="entry_summary"]/a/@href').extract()[0]
            footer = content.xpath('div[@class="entry_footer"]')
            article_author = footer.xpath('a/text()').extract()[0]
            matched = re.match('評論\((\d+)\)', footer.xpath('span[@class="comment"]/a/text()').extract()[0])
            article_comments =  matched.group(1) if matched else 0
            article_view = footer.xpath('span[@class="view"]').extract()[0]
            article_tag = footer.xpath('span[@class="tag"]').extract()[0]

            article_item = ArticleItem()
            article_item['article_url'] = article_url
            article_item['article_title'] = article_title
            article_item['article_front_image_url'] = article_front_image_url
            article_item['article_author'] = article_author
            article_item['article_comments'] = article_comments
            article_item['article_view'] = article_view
            article_item['article_tag'] = article_tag
            article_item['article_id'] = get_md5(article_url)
            yield Request(url=parse.urljoin(response.url ,article_url),meta={"item":article_item}, callback=self.parse_detail)
        pass

    def parse_detail(self, response):
        pass


# 有些時候 咱們能夠使用 Itemloader 來讓咱們的代碼變得更友好
item_loadder = ItemLoader(item=ArticleItem(), response=response)
item_loadder.add_xpath(field_name="article_url", xpath="//div[@id='news_list']/div[@class='news_block']/div[@class='content']/h2/a/@href")
.
.
.
next_urls_selector = response.xpath('//*[@id="sideleft"]/div[5]/a[11]')

總結 對付反爬

訪問 500  通常是 UA 沒設置
cookie  攜帶
token 
salt
sign
ctrl + shift + f 很好用 在查找 js 調用時候
cookies  池
ip 代理 池

pip3 install faker

https://cmder.net/

搭建本身的 ip 代理池

mongo db 安裝使用

# 建立 ipproxy 數據庫  若是沒有就建立
use ipproxy;

### 插入數據
db.ipproxy.insert({"ip_port":"192.168.0.18:5678"})

# 刪除 數據庫
db.dropDatabase()

# 刪除集合
db.collection.drop()

# 查詢集合
db.ipproxy.find().pretty()

 db.createCollection("mycol", { capped : true, autoIndexId : true, size : 
   6142800, max : 10000 } )

db.ipproxy.drop()
相關文章
相關標籤/搜索