今回は、Himalaya の人気コラムの下にあるすべてのラジオ局の各チャンネルの情報と、チャンネル内の各音声データのさまざまな情報をクロールし、後で使用できるようにクロールされたデータを mongodb に保存しました。今回のデータ量は約70万件です。音声データには、音声ダウンロードアドレス、チャンネル情報、紹介文などが含まれており、多数あります。
昨日初めて面接を受けました。2年生の夏休みにインターンに行く予定だったので、音声データを解析するために来ました。ヒマラヤ。データが這い降りてくる。現在、3件の面接、もしくは最終面接の連絡を待っている状態です。 (一定の評価が得られるので成功失敗問わずとても嬉しいです)
IDE: Pycharm 2017
Python3.6
pymongo 3.4.0
リクエスト 2.14.2
lxml 3.7.2
BeautifulSoup 4.5.3
1.各ページには、各チャネルの下に多数のオーディオがあり、一部のチャネルには多数のページネーションもあります。クロール計画: 84 ページをループし、各ページを解析して、各チャンネルの名前、画像リンク、チャンネル リンクを取得して、mongodb に保存します。
2. 開発者モードを開いてページを分析し、必要なデータの場所をすばやく取得します。次のコードは、すべての人気チャンネルの情報を取得して mongodb に保存することを実現します。
start_urls = ['http://www.ximalaya.com/dq/all/{}'.format(num) for num in range(1, 85)]for start_url in start_urls:html = requests.get(start_url, headers=headers1).text soup = BeautifulSoup(html, 'lxml')for item in soup.find_all(class_="albumfaceOutter"):content = {'href': item.a['href'],'title': item.img['alt'],'img_url': item.img['src'] } print(content)
3 次のステップは、各チャンネルのすべての音声データを分析ページから取得することです。たとえば、このリンクを入力した後のページ構造を分析します。各オーディオには特定の ID があり、div 内の属性から取得できることがわかります。個別の ID に変換するには、split() と int() を使用します。
4. 次に、オーディオリンクをクリックして開発者モードに入り、ページを更新して XHR をクリックし、json リンクをクリックしてこのオーディオの詳細情報をすべて表示します。
html = requests.get(url, headers=headers2).text numlist = etree.HTML(html).xpath('//div[@class="personal_body"]/@sound_ids')[0].split(',')for i in numlist: murl = 'http://www.ximalaya.com/tracks/{}.json'.format(i)html = requests.get(murl, headers=headers1).text dic = json.loads(html)
5. 上記はチャンネルのメインページ上のすべてのオーディオ情報のみを分析しますが、実際にはチャンネルのオーディオリンクには多くのページネーションがあります。
html = requests.get(url, headers=headers2).text ifanother = etree.HTML(html).xpath('//div[@class="pagingBar_wrapper"]/a[last()-1]/@data-page')if len(ifanother):num = ifanother[0] print('本频道资源存在' + num + '个页面')for n in range(1, int(num)): print('开始解析{}个中的第{}个页面'.format(num, n)) url2 = url + '?page={}'.format(n)# 之后就接解析音频页函数就行,后面有完整代码说明
6. 全コード
完全なコードアドレス github.com/rieuse/learnPython
__author__ = '布咯咯_rieuse'import jsonimport randomimport timeimport pymongoimport requestsfrom bs4 import BeautifulSoupfrom lxml import etree clients = pymongo.MongoClient('localhost') db = clients["XiMaLaYa"] col1 = db["album"] col2 = db["detaile"] UA_LIST = [] # 很多User-Agent用来随机使用可以防ban,显示不方便不贴出来了 headers1 = {} # 访问网页的headers,这里显示不方便我就不贴出来了 headers2 = {} # 访问网页的headers这里显示不方便我就不贴出来了def get_url(): start_urls = ['http://www.ximalaya.com/dq/all/{}'.format(num) for num in range(1, 85)]for start_url in start_urls: html = requests.get(start_url, headers=headers1).text soup = BeautifulSoup(html, 'lxml')for item in soup.find_all(class_="albumfaceOutter"): content = {'href': item.a['href'],'title': item.img['alt'],'img_url': item.img['src'] } col1.insert(content) print('写入一个频道' + item.a['href']) print(content) another(item.a['href']) time.sleep(1)def another(url): html = requests.get(url, headers=headers2).text ifanother = etree.HTML(html).xpath('//div[@class="pagingBar_wrapper"]/a[last()-1]/@data-page')if len(ifanother): num = ifanother[0] print('本频道资源存在' + num + '个页面')for n in range(1, int(num)): print('开始解析{}个中的第{}个页面'.format(num, n)) url2 = url + '?page={}'.format(n) get_m4a(url2) get_m4a(url)def get_m4a(url): time.sleep(1) html = requests.get(url, headers=headers2).text numlist = etree.HTML(html).xpath('//div[@class="personal_body"]/@sound_ids')[0].split(',')for i in numlist: murl = 'http://www.ximalaya.com/tracks/{}.json'.format(i) html = requests.get(murl, headers=headers1).text dic = json.loads(html) col2.insert(dic) print(murl + '中的数据已被成功插入mongodb')if __name__ == '__main__': get_url()
7. 非同期形式に変更するだけで高速になります。通常よりも 1 分あたり 100 個近く多くのデータを取得しようとしました。このソースコードはgithubにもあります。
以上がPython クローラーの音声データの例の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。