轉自:http://blog.csdn.net/sunnyxiaohu/article/details/50787430
大概花了一個星期的時間,學習了一下網絡爬蟲的知識,現在使用scrapy能爬一些基本的網頁,圖片,解決網頁編碼兼容問題,基礎的模擬登陸。對于有些模擬登陸,由于其提交的表單要經過js進行處理后提交;更難的其網頁也是經js渲染的,要學會一步步去分析,沒有太多的去深入,但我會提到基本的分析方法。
參考文章: 1、http://www.runoob.com/ 一個很好的語言語法入門學習的網站,我主要用其學習了Python的語法。 2、http://blog.csdn.net/column/details/why-bug.html 此博客講了一些網絡爬蟲的基礎知識,包括http,url等,而且一步步講解了實現爬蟲的整個過程。 3、http://doc.scrapy.org/en/latest/intro/tutorial.html scrapy框架的學習教程,從安裝講到應用到常見問題,是個不可多得的參考手冊,至少過一遍,對于想深入研究的同學,一定要多看幾遍。 4、http://blog.csdn.net/u012150179/article/details/34486677 對于中文輸出與保存,實現多網頁的爬取,做了實現。 5、http://www.jianshu.com/p/b7f41df6202d http://www.jianshu.com/p/36a39ea71bfd 對于怎么實現模擬登陸做了較好的解釋和實現,當然由于技術的不斷更新和動態變化,網站的反爬蟲的技術也在不斷更新,具體情況,應具體分析。
下面正式進入學習: 環境:Ubuntu14.04 一、python 1、python的下載和安裝:https://www.python.org/downloads/ 在鏈接中找到自己需要的版本,記得在研究中基本不用version>3.0的版本,然而有為了支持一些新的功能,基本上version>2.70 and version<3.0是一個比較合適的選擇。由于ubuntu14.04的底層有些使用python實現的,所以都帶了python,(python2.74的版本或者其它)如果需要不同的版本可在不刪除原有版本的基礎上下載新版本,并修改軟鏈接即可。ln -s python pythonx.xx中間若有問題,請自行百度解決。 2、python的基礎知識學習。熟悉一下基本的語法,重點關注列表,元組,字典,函數和類。其它的若有問題,再返回去學習吧,學習鏈接在參考中已給出,練習一下,一兩天就差不多能搞定了。
二、網絡爬蟲的基礎知識 1、網絡爬蟲的定義、瀏覽網頁的過程、URI和URL的概念和舉例、URL的理解和舉例。 2、正則表達式 自己練習一下,如果記不住了看看下面的表。
三、scrapy 1、scrapy的安裝 http://doc.scrapy.org/en/latest/intro/install.html 根據你自己應用的平臺進行選擇。比較簡單,不做過多的解釋。 2、一個scrapy例子 http://doc.scrapy.org/en/latest/intro/tutorial.html 有幾點要注意一下:一是知道如何去調試,二是xpath()和CSS(),還有要學會使用firebox和firebug分析網頁源碼和表單提交情況,看到前面,我們基本能實現單網頁的爬取。 3、講講scrapy框架 對scrapy的框架和運行有一個具體的思路之后我們才能更好的了解爬蟲的整個情況,尤其是出了問題之后的調試 http://blog.csdn.net/u012150179/article/details/34441655 http://s1.VeVb.com/20170308/d1whunqz55w59.png 4、scrapy自動多網頁爬取 總結起來實現有三種方式:第一種,先PRase眼前的url,得到各個item后,在獲得新的url,調用prase_item進行解析,在prase_item中又callback parse function 。第二種,也就是例子(scrapy的一個例子)中后部分提到的:
prase只做url的獲取,具體的解析工作交給prase_dir_contents去做。第三種、就是根據具體的爬蟲去實現了,Generic Spiders(例子中我們用的是Simple Spiders)中用的比較多的有CrawlSpider,這里我們介紹這個的實現
import scrapyfrom scrapy.spiders import CrawlSpider, Rulefrom scrapy.linkextractors import LinkExtractorclass MySpider(CrawlSpider): name = 'example.com' allowed_domains = ['example.com'] start_urls = ['http://www.example.com'] rules = ( # Extract links matching 'category.php' (but not matching 'subsection.php') # and follow links from them (since no callback means follow=True by default). follow Rule(LinkExtractor(allow=('category/.php', ), deny=('subsection/.php', ))), # Extract links matching 'item.php' and parse them with the spider's method parse_item. process Rule(LinkExtractor(allow=('item/.php', )), callback='parse_item'), ) def parse_item(self, response): .......12345678910111213141516171819201234567891011121314151617181920這便是其的Link Extractors機制。 5、中文輸出與存儲編碼 http://blog.csdn.net/u012150179/article/details/34450547 存儲:在 item.py中編碼:item[‘title’] = [t.encode(‘utf-8’) for t in title] ,在pipe.py中解碼:
import json import codecs class W3SchoolPipeline(object): def __init__(self): self.file = codecs.open('vevb_data_utf8.json', 'wb', encoding='utf-8') def process_item(self, item, spider): line = json.dumps(dict(item)) + '/n' # print line self.file.write(line.decode("unicode_escape")) return item 1234567891011121312345678910111213輸出:
for t in title: print t.encode('utf-8') 12126、圖片或者文件的下載 http://doc.scrapy.org/en/latest/topics/media-pipeline.html 這里,主要提供一個抓取妹子圖片的例子。注意怎么實現文件名的替換與改寫。
class ImagedownPipeline(object): def process_item(self, item, spider): if 'image_url' in item: #images = [] dir_path = '%s/%s' % (settings.IMAGES_STORE, spider.name)# if not os.path.exists(dir_path):# os.makedirs(dir_path) for image_url in item['image_url']: image_page = item['image_page'] dir_path = '%s/%s' %(dir_path, image_page) if not os.path.exists(dir_path): os.makedirs(dir_path) us = image_url.split('/')[3:] image_file_name = '_'.join(us) file_path = '%s/%s' % (dir_path, image_file_name) #images.append(file_path) if os.path.exists(file_path): continue with open(file_path, 'wb') as handle: response = requests.get(image_url, stream=True) for block in response.iter_content(): #if not block: # break handle.write(block) #item['images'] = images return item123456789101112131415161718192021222324252627282930123456789101112131415161718192021222324252627282930this kind of process would make more efficiency
class MyImagesPipeline(ImagesPipeline): def item_completed(self, results, item, info): image_paths = [x['path'] for ok, x in results if ok]# print settings.IMAGES_STORE + image_paths[0] if not image_paths: raise DropItem("Item contains no images") for img_url in item['image_urls']: us = img_url.split('/')[3:] newname = '_'.join(us) dir_path = settings.IMAGES_STORE+"full/"+item['image_page']+"/"# print dir_path if not os.path.exists(dir_path): os.makedirs(dir_path) os.rename(settings.IMAGES_STORE + image_paths[0], dir_path + newname) return item123456789101112131415161712345678910111213141516177、scrapy模擬登陸 此處不做過多的解釋,給出兩個例子。里面分析的很詳細 http://www.jianshu.com/p/b7f41df6202d http://www.jianshu.com/p/36a39ea71bfd 還有,有時需要模擬Request的headers,這在http://doc.scrapy.org/en/latest/topics/request-response.html 中有很好的說明,至于怎么找到對應的headers,可通過firebug或者其它。 8、處理js渲染過的網頁 …… 9、驗證碼的識別 ……. 10、分布式爬蟲的實現 …….
新聞熱點
疑難解答