

下記にてpythonのスクレイピングを実行しているのですが、

[code]

      Traceback (most recent call last):
      File "link_network.py", line 81, in <module>
        G = make_network(args.url, urls)
      File "link_network.py", line 33, in make_network
        article_name= url.replace(entry_url,"").replace("/","-")
    AttributeError: 'NoneType' object has no attribute 'replace'
    
[/code]

のエラーが表示されております。  
どの部分にどう記載すればよいのかわからず、是非教えていただきたく存じます。

修正

[code]

    def extract_url(root_url):
        page = 1
        is_articles = True
        urls = []
    
        while is_articles:
            UserAgent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Safari/605.1.15'
            html = request.urlopen(request.Request(root_url, None, {'User-Agent': UserAgent}))
            soup = BeautifulSoup(html, "html.parser")
            articles = soup.find_all("a")
            for article in articles:
                href = article.get("href")
                if href:
                    urls.append(href)
            is_articles = False
        return urls 
    
[/code]


CC BY-SA 4.0
2020-05-03T13:10:33.433
66250
2022-11-23T05:07:40.927
2020-05-05T03:08:53.080
39965
39965
question
python python3 web-scraping
pythonでスクレイピング実行時でのエラーについて。


<https://docs.python.org/ja/3.7/howto/urllib2.html#headers>

このページを参考にするとヘッダーにuser agentが設定できると思います。

また、スクレイピングによって非常に高頻度のアクセスをかけるとサービスによってはipごとブロックをする場合があります。  
その際に403が返ることも考えられますので最低でも１秒感覚のアクセスを心がけましょう。  
こうなってしまっては同じipからはアクセスすることが不可能になるため気をつけたほうがいいです。  
最悪の場合警察沙汰です。

<https://ja.wikipedia.org/wiki/%E5%B2%A1%E5%B4%8E%E5%B8%82%E7%AB%8B%E4%B8%AD%E5%A4%AE%E5%9B%B3%E6%9B%B8%E9%A4%A8%E4%BA%8B%E4%BB%B6>


CC BY-SA 4.0
2020-05-03T13:53:43.380
66251
2020-05-03T13:53:43.380
39966
66250
answer


少なくとも UserAgent については、

[code]

    request.urlopen(URL)
    
[/code]

というような形式で open している部分を、URL 文字列ではなく、request.Request() オブジェクトを与えることで、指定できます。

[code]

    UserAgent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Safari/605.1.15'
    
    request.urlopen(request.Request(URL, None, {'User-Agent': UserAgent}))
    
[/code]

参考：[urllib.request --- URL
を開くための拡張可能なライブラリ](https://docs.python.org/ja/3.8/library/urllib.request.html)

* * *

> NameError: name 'html' is not defined

については、`def make_network(root_url, urls):` の中の

[code]

    try:
        UserAgent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Safari/605.1.15'
        html = request.urlopen(request.Request(url, None, {'User-Agent': UserAgent}))
    except urllib.error.HTTPError as e: 
        print(e.reason)
    except urllib.error.URLError as e: 
        print(e.reason)
    soup = BeautifulSoup(html, "html.parser")
    
[/code]

が原因でしょう。html が try ブロックの内側のスコープにあるので、`BeautifulSoup(html, "html.parser")`
の第1引数の html とは別物となり、未定義なのが原因です。

[code]

    html = ''
    try:
        UserAgent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Safari/605.1.15'
        html = request.urlopen(request.Request(url, None, {'User-Agent': UserAgent}))
    except urllib.error.HTTPError as e: 
        print(e.reason)
    except urllib.error.URLError as e: 
        print(e.reason)
    soup = BeautifulSoup(html, "html.parser")
    
[/code]

としてみたらどうでしょうか？


CC BY-SA 4.0
2020-05-03T13:56:19.057
66253
2020-05-04T12:19:40.423
2020-05-04T12:19:40.423
7290
7290
66250
answer


もしかしたら `placeholder hyperlink` が存在するのかもしれません。`placeholder hyperlink` というのは
`href` 属性のない `a` 要素の事です。

[Elements/a - W3C Wiki](https://www.w3.org/wiki/Elements/a)

> If the href attribute is not specified, the element represents a placeholder
> hyperlink.

`placeholder hyperlink` が存在する場合、`extract_url` 関数の以下の部分で `urls` 変数(リスト)に `None`
が含まれる事になります。

[code]

    def extract_url(root_url):
               :    
        while is_articles:
               :    
            articles = soup.find_all("a")
            for article in articles:
                urls.append(article.get("href"))
               :    
        return urls
    
[/code]

`article.get("href")` の戻り値が `None` の場合(`placeholder hyperlink`)は `urls`
に含めない様に変更します。

[code]

            for article in articles:
                href = article.get("href")
                if href:
                    urls.append(href)
    
[/code]

これで試してみて下さい。


CC BY-SA 4.0
2020-05-04T14:06:46.340
66288
2020-05-04T14:06:46.340
66250
answer