1

私はscrapyを使用してWebサイトをクロールし、そこからデータを抽出しています。scrapyは正規表現ベースのルールを使用して、ページを解析する必要があるか、リンクをたどる必要があるかを確認しています。

スパイダーに再開機能を実装しているので、最後にアクセスしたページからクロールを続けることができます。このため、スパイダーの起動時にデータベースから最後にたどったリンクを取得します。

私のサイトのURLはのようhttp://foobar.com/page1.htmlに見えるので、通常、このようなすべてのリンクをたどるルールの正規表現は、のようになります/page\d+\.html

しかし、たとえば15ページ以上に一致するように正規表現を作成するにはどうすればよいですか?また、事前に開始点がわからないので、実行時にこの正規表現を生成するにはどうすればよいですか?

4

4 に答える 4

3

ページ番号をグループ化してから、修飾されているかどうかを確認してください。

>>> m=re.match("/page(\d+)\.html","/page18.html")
>>> if m:
    ID=int(m.groups()[0])
>>> ID > 15
True

または、より具体的には、あなたが要求したもの:

>>> def genRegex(n):
    return ''.join('[' + "0123456789"[int(d):] + ']' for d in str(n))

>>> genRegex(123)
'[123456789][23456789][3456789]'
于 2011-03-05T18:08:56.807 に答える
2

これを試して:

def digit_match_greater(n):
    digits = str(n)
    variations = []
    # Anything with more than len(digits) digits is a match:
    variations.append(r"\d{%d,}" % (len(digits)+1))
    # Now match numbers with len(digits) digits.
    # (Generate, e.g, for 15, "1[6-9]", "[2-9]\d")
    # 9s can be skipped -- e.g. for >19 we only need [2-9]\d.
    for i, d in enumerate(digits):
        if d != "9": 
            pattern = list(digits)
            pattern[i] = "[%d-9]" % (int(d) + 1)
            for j in range(i+1, len(digits)):
                pattern[j] = r"\d"
            variations.append("".join(pattern))
    return "(?:%s)" % "|".join("(?:%s)" % v for v in variations)

パラメータよりも大きい数値に一致させる方が簡単であることが判明したため、15を指定すると、16以上の数値に一致する文字列が返されます。具体的には...

(?:(?:\d{3,})|(?:[2-9]\d)|(?:1[6-9]))

\d+次に、次のように、の代わりにこれを式に置き換えることができます。

exp = re.compile(r"page%s\.html" % digit_match_greater(last_page_visited))
于 2011-03-05T18:49:16.820 に答える
2

Kabieの答えを少し拡張します:

def genregex(n):
    nstr = str(n)
    same_digit = ''.join('[' + "0123456789"[int(d):] + ']' for d in nstr)
    return "\d{%d,}|%s" % (len(nstr) + 1, same_digit)

Webサイトで先行ゼロが発生した場合は、先行ゼロを処理するように簡単に変更できます。しかし、これは間違ったアプローチのようです。

Scrapyには他にもいくつかのオプションがあります。おそらくSgmlLinkExtractorを使用しています。この場合、最も簡単な方法は、独自の関数をprocess_valueキーワード引数として渡して、カスタムフィルタリングを実行することです。

CrawlSpiderはかなりカスタマイズできますが、タスクに合わない場合は、BaseSpiderを確認する必要があります。

于 2011-03-10T19:06:59.480 に答える
0
>>> import regex
>>> import random
>>> n=random.randint(100,1000000)
>>> n
435220
>>> len(str(n))
>>> '\d'*len(str(n))
'\\d\\d\\d\\d\\d\\d'
>>> reg='\d{%d}'%len(str(n))
>>> m=re.search(reg,str(n))
>>> m.group(0)
'435220'
于 2011-03-05T18:14:15.600 に答える