Python爬虫実戦計画:第2週作業
9712 ワード
北京市场-中古市场-すべての商品カテゴリの个人カテゴリの商品情报を取得する
最近仕事でずっと忙しくて、今まで延ばしてやっと宿題を終えて、本当に耻ずかしいです.統計してみると、全部で約3万件のデータが登り、1ページに多くの重複データがある.プロセス:1.すべての欄のurl 2を取得します.各欄のすべての商品リンク2.1を取得する:欄に対応する株を捕まえる規則を確立する.各商品の詳細分析:1.すべての欄のurl a.欄のurlを'dlに取得する.fenlei>dt>a'経路下b.携帯電話番号欄を取り除くと、何も入っていません.各欄の第1ページの商品リンクaを取得する.商品リンクキャプチャ規則を確立する:テストを経て全部で3種類のキャプチャ規則がある:i.規則1)'div.infocon tr.zzinfo td.t a.t'のほとんどの欄はこの規則iiです.ルール2)'a.ft-tit'2)欄:設備事務用品、農産物、遊休品、仮想物品iii.ルール3:1)'div.layoutlist div.infor 01>a'2)欄:雑多、無料贈呈、物品取引残りはルール1 b.捕まえた商品urlをデータベースに格納する:3.各欄の各ページの商品リンクを取得する:a.観察により、i.各欄の第1ページは「http://bj.ganji.com/コラムurl/'ii.最初のページを除いた各ページは、http://bj.ganji.com/欄/oページ番号/'iii.ページ番号はいずれも2から始まる、2ページ目b.境界検査:i.最後のページに登るとiiの登りが停止することを示す.観察により,各欄の各商品リストページには,3つの境界形式1)最後のページの次のページ,後に空の商品リストのページがあることが分かった.2)最後のページの次のページには,いくつかの古いデータ(商品)リストページの最初の形式があり,ページ商品ページリストが空であるかどうかを検出し,境界判断を行うことができる.第二の形式は、判断しにくい.最後のページの次のページにはまだ商品リストがあるので、古いデータだけですが、私たちが望んでいるわけではありません.iii.so,別の境界判断形式が必要である:1)通常のページには各ページに次のページのラベルがあり,最後のページの次のページには次のページのラベルがないことが分かった2)別のページがある:a)最も次のページのラベルがない,最後のページの次のページには,空の商品リストページであるか,時代遅れであるか,商品リストページである.b)so,簡単な処理のために.私たちは、このタイプの最後のページpassを落とすことにしました.各ページの商品情報を取得:商品情報ページの2種類のページ:1.転送網1)取得:タイトル、価格、タイプ2.取得:タイトル、価格、タイプ、地域.実装:具体的には3つの実装に分けられ、1つのMongoDBプロファイル:1.ページリンク爬取器:すべてのページのすべての商品リンクを爬取する.ページ詳細爬取器:すべての商品リンクページの商品情報を爬取する.3.メインプログラム:エントリプログラム、リンク爬取器を呼び出し、詳細爬取器.4.MongoDBプロファイルは具体的なコード:MongoDBプロファイル:
リンク爬虫器:
ページ詳細:
メインプログラム:
最近仕事でずっと忙しくて、今まで延ばしてやっと宿題を終えて、本当に耻ずかしいです.統計してみると、全部で約3万件のデータが登り、1ページに多くの重複データがある.プロセス:1.すべての欄のurl 2を取得します.各欄のすべての商品リンク2.1を取得する:欄に対応する株を捕まえる規則を確立する.各商品の詳細分析:1.すべての欄のurl a.欄のurlを'dlに取得する.fenlei>dt>a'経路下b.携帯電話番号欄を取り除くと、何も入っていません.各欄の第1ページの商品リンクaを取得する.商品リンクキャプチャ規則を確立する:テストを経て全部で3種類のキャプチャ規則がある:i.規則1)'div.infocon tr.zzinfo td.t a.t'のほとんどの欄はこの規則iiです.ルール2)'a.ft-tit'2)欄:設備事務用品、農産物、遊休品、仮想物品iii.ルール3:1)'div.layoutlist div.infor 01>a'2)欄:雑多、無料贈呈、物品取引残りはルール1 b.捕まえた商品urlをデータベースに格納する:3.各欄の各ページの商品リンクを取得する:a.観察により、i.各欄の第1ページは「http://bj.ganji.com/コラムurl/'ii.最初のページを除いた各ページは、http://bj.ganji.com/欄/oページ番号/'iii.ページ番号はいずれも2から始まる、2ページ目b.境界検査:i.最後のページに登るとiiの登りが停止することを示す.観察により,各欄の各商品リストページには,3つの境界形式1)最後のページの次のページ,後に空の商品リストのページがあることが分かった.2)最後のページの次のページには,いくつかの古いデータ(商品)リストページの最初の形式があり,ページ商品ページリストが空であるかどうかを検出し,境界判断を行うことができる.第二の形式は、判断しにくい.最後のページの次のページにはまだ商品リストがあるので、古いデータだけですが、私たちが望んでいるわけではありません.iii.so,別の境界判断形式が必要である:1)通常のページには各ページに次のページのラベルがあり,最後のページの次のページには次のページのラベルがないことが分かった2)別のページがある:a)最も次のページのラベルがない,最後のページの次のページには,空の商品リストページであるか,時代遅れであるか,商品リストページである.b)so,簡単な処理のために.私たちは、このタイプの最後のページpassを落とすことにしました.各ページの商品情報を取得:商品情報ページの2種類のページ:1.転送網1)取得:タイトル、価格、タイプ2.取得:タイトル、価格、タイプ、地域.実装:具体的には3つの実装に分けられ、1つのMongoDBプロファイル:1.ページリンク爬取器:すべてのページのすべての商品リンクを爬取する.ページ詳細爬取器:すべての商品リンクページの商品情報を爬取する.3.メインプログラム:エントリプログラム、リンク爬取器を呼び出し、詳細爬取器.4.MongoDBプロファイルは具体的なコード:MongoDBプロファイル:
#coding=utf-8
"""mongoDB """
from pymongo import MongoClient
client = MongoClient('localhost',27017)
db = client['ganji']
# url
bj_item_urls_collenction = db['bj_item_urls_collenction']
# url
bj_page_urls_collenction = db['bj_page_urls_collenction']
#
bj_page_info_collenction = db['bj_page_info_collenction']
リンク爬虫器:
#coding=utf-8
import time
import requests
import mongoConfig
from bs4 import BeautifulSoup
bj_item_urls_collenction = mongoConfig.bj_item_urls_collenction
bj_page_urls_collenction = mongoConfig.bj_page_urls_collenction
def get_html(url):
""" html """
html = None
headers = {
'User-Agent': ('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)'
'Chrome/54.0.2840.87 Safari/537.36')
}
#request http status code , 404
#
try:
response = requests.get(url,headers=headers)
if response.status_code == 200:
html = response.text
print ' --',url
else:
print 'HTTP ',response.status_code,url
except requests.Timeout as e:
print ' --- ',url
time.sleep(3)
return html
def get_all_category_links(url):
""" url"""
html = get_html(url)
soup = BeautifulSoup(html, 'lxml')
base_url = 'http://bj.ganji.com{}'
dl = soup.select('dl.fenlei > dt > a')
links = None
if dl:
links = [base_url.format(link.get('href')) for link in dl]
else:
print ' ',url
if 'http://bj.ganji.com/shoujihaoma/' in links:
links.remove('http://bj.ganji.com/shoujihaoma/')
print ' http://bj.ganji.com/shoujihaoma/'
return links
def get_item_links(url):
""" url"""
html = get_html(url)
soup = BeautifulSoup(html, 'lxml')
#
item_rules = ['div.infocon tr.zzinfo td.t a.t','a.ft-tit','div.layoutlist div.infor01 > a']
#a.next
if soup.find('a', 'next'):
for item_rule in item_rules:
items = soup.select(item_rule)
if items:
return [link.get('href').split('?')[0] for link in items]
return None
def save_to_db(infos):
""" """
start = bj_item_urls_collenction.find().count()
for url in infos:
if not bj_item_urls_collenction.find_one({'url': url}):
bj_item_urls_collenction.insert_one({'url': url})
#print ' {}'.format(url)
else:
pass
#print ' {} '.format(url)
end = bj_item_urls_collenction.find().count()
print ' {} '.format(len(infos))
print ' {} '.format(end-start)
def process_main(url):
""" """
def page_zhuaqu(url):
is_continue = True
if not bj_page_urls_collenction.find_one({'url': url}):
links = get_item_links(url)
if links:
save_to_db(links) # url
bj_page_urls_collenction.insert_one({'url': url})
is_continue = True
print ' {} '.format(url)
else:
print ' , ', url
is_continue = False
else:
print ' {} '.format(url)
return is_continue
#
page_zhuaqu(url)
#
page = 2
is_continue = True
base_url = url + 'o{}/'
while is_continue:
page_url = base_url.format(page)
is_continue = page_zhuaqu(page_url)
page += 1
ページ詳細:
#coding=utf-8
import time
import requests
import mongoConfig
from bs4 import BeautifulSoup
bj_item_urls_collenction = mongoConfig.bj_item_urls_collenction
bj_page_info_collenction = mongoConfig.bj_page_info_collenction
def get_html(url):
""" html """
html = None
headers = {
'User-Agent': ('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)'
'Chrome/54.0.2840.87 Safari/537.36')
}
#request http status code , 404
#
try:
response = requests.get(url,headers=headers)
if response.status_code == 200:
html = response.text
print ' --',url
else:
print 'HTTP ',response.status_code,url
except requests.Timeout as e:
print ' --- ',url
time.sleep(3)
return html
def price_to_float(price_tag):
""" float
: :200
+ :1.2 12000
:
"""
price = None
if price_tag:
price_str = price_tag[0].get_text()
if price_str == u' ':
price = price_str
elif price_str.endswith(u' '):
price = float(price_str[:-2]) * 10000
else:
price = float(price_str)
return price
def zhuanzhuan_page_parse(soup,url):
""" ,
: , , """
area = soup.select('div.palce_li > span > i')
title = soup.select('h1.info_titile')
price = soup.select('span.price_now > i')
data = {'url':url,'title': title[0].get_text() if title else None,
'price': price_to_float(price),
'area':area[0].get_text() if area else None
}
return data
def ganji_page_parse(soup,url):
"""
: , , , """
title= soup.select('h1.title-name')[0].get_text()
item_soup = soup.select('ul.det-infor > li')
item_type = item_soup[0].find('a').get_text()
price = price_to_float(item_soup[1].select('i'))
area_soup = item_soup[2].find_all('a')
# BeautifulSoup unicode , unicode , 。
area = u'{}-{}'.format(area_soup[0].string.strip(), area_soup[1].string.strip())
data = {
'url':url,
'title':title,
'tiem_type':item_type,
'price':price,
'area':area
}
return data
def process_main(url):
""" , """
if not bj_page_info_collenction.find_one({'url':url}):
html = get_html(url)
soup = BeautifulSoup(html, 'lxml')
data = None
if url.startswith('http://bj.ganji.com'):
data = ganji_page_parse(soup,url)
elif url.startswith('http://zhuanzhuan.ganji.com'):
data = zhuanzhuan_page_parse(soup,url)
bj_page_info_collenction.insert_one(data)
print ' {}'.format(url)
else:
print ' {}'.format(url)
メインプログラム:
#coding=utf-8
import multiprocessing
import mongoConfig
import links_spider
import pages_spider
if __name__ == '__main__':
# ,
url = 'http://bj.ganji.com/wu/'
links_urls = links_spider.get_all_category_links(url)
# , cpu
pool = multiprocessing.Pool()
pool.map_async(links_spider.process_main,links_urls)
pool.close()
pool.join()
# ,
items_urls =[items['url'] for items in mongoConfig.bj_item_urls_collenction.find({})]
pool = multiprocessing.Pool()
pool.map_async(pages_spider.process_main,items_urls)
pool.close()
pool.join()
print ' {} url'.format(mongoConfig.bj_item_urls_collenction.find().count())
print ' {} '.format(mongoConfig.bj_page_info_collenction.find().count())