基於scrapy的分布式爬蟲抓取新浪微博個人信息和微博內容存入MySQL


為了學習機器學習深度學習和文本挖掘方面的知識,需要獲取一定的數據,新浪微博的大量數據可以作為此次研究歷程的對象

一、環境准備

 
python 2.7 
scrapy框架的部署(可以查看上一篇博客的簡要操作,傳送門: 點擊打開鏈接
mysql的部署(需要的資源百度網盤鏈接: 點擊打開鏈接
heidiSQL數據庫可視化
 
本人的系統環境是 win 64位的 所以以上環境都是需要兼容64位的
 
 

二、scrapy組件和數據流介紹

\

1、Scrapy architecture


組件Scrapy Engine

引擎負責控制數據流在系統中所有組件中流動,並在相應動作發生時觸發事件。

調度器(Scheduler)

調度器從引擎接受request並將他們入隊,以便之后引擎請求他們時提供給引擎。

下載器(Downloader)

下載器負責獲取頁面數據並提供給引擎,而后提供給spider。

Spiders

Spider是Scrapy用戶編寫用於分析response並提取item(即獲取到的item)或額外跟進的URL的類。 每個spider負責處理一個特定(或一些)網站。Item PipelineItem Pipeline負責處理被spider提取出來的item。典型的處理有清理、 驗證及持久化(例如存取到數據庫中)。

下載器中間件(Downloader middlewares)

下載器中間件是在引擎及下載器之間的特定鈎子(specific hook),處理Downloader傳遞給引擎的response。 其提供了一個簡便的機制,通過插入自定義代碼來擴展Scrapy功能。更多內容請看 下載器中間件(Downloader Middleware) 。

Spider中間件(Spider middlewares)

Spider中間件是在引擎及Spider之間的特定鈎子(specific hook),處理spider的輸入(response)和輸出(items及requests)。 其提供了一個簡便的機制,通過插入自定義代碼來擴展Scrapy功能。更多內容請看 Spider中間件(Middleware) 。

 

 

2、數據流(Data flow)


Scrapy中的數據流由執行引擎控制,其過程如下:


1.引擎打開一個網站(open a domain),找到處理該網站的Spider並向該spider請求第一個要爬取的URL(s)。

2.引擎從Spider中獲取到第一個要爬取的URL並在調度器(Scheduler)以Request調度。

3.引擎向調度器請求下一個要爬取的URL。

4.調度器返回下一個要爬取的URL給引擎,引擎將URL通過下載中間件(請求(request)方向)轉發給下載器(Downloader)。

5.一旦頁面下載完畢,下載器生成一個該頁面的Response,並將其通過下載中間件(返回(response)方向)發送給引擎。

6.引擎從下載器中接收到Response並通過Spider中間件(輸入方向)發送給Spider處理。

7.Spider處理Response並返回爬取到的Item及(跟進的)新的Request給引擎。

8.引擎將(Spider返回的)爬取到的Item給Item Pipeline,將(Spider返回的)Request給調度器。

9.(從第二步)重復直到調度器中沒有更多地request,引擎關閉該網站。

以上組件和數據流的部分是參考別的的介紹,覺得描述的挺好,比較容易理解整個框架的結構。下面是干貨:

三、scrapy工程對象

在你需要創建工程的目錄底下啟動cmd命令(按住shift鍵右鍵選擇在此處打開命令窗口) 執行:scrapy startproject weibo
會在當前目錄下生成scrapy框架的目錄結構:
本人用的IDE是pycharm ,用IDE打開工程,工程最終的目錄結構如圖所示:


 
 

1、item.py的內容:

[python]  view plain  copy
 
  1. # encoding=utf-8  
  2.   
  3. from scrapy.item import Item, Field  
  4.   
  5.   
  6. class InformationItem(Item):  
  7.     #關注對象的相關個人信息  
  8.     _id = Field()  # 用戶ID  
  9.     Info = Field() # 用戶基本信息  
  10.     Num_Tweets = Field()  # 微博數  
  11.     Num_Follows = Field()  # 關注數  
  12.     Num_Fans = Field()  # 粉絲數  
  13.     HomePage = Field() #關注者的主頁  
  14.   
  15.   
  16. class TweetsItem(Item):  
  17.     #微博內容的相關信息  
  18.     _id = Field()  # 用戶ID  
  19.     Content = Field()  # 微博內容  
  20.     Time_Location = Field()  # 時間地點  
  21.     Pic_Url = Field()  # 原圖鏈接  
  22.     Like = Field()  # 點贊數  
  23.     Transfer = Field()  # 轉載數  
  24.     Comment = Field()  # 評論數  

定義了兩個類,InformationItem獲取關注列表用戶的個人信息,TweetsItem獲取微博內容

2、weibo_spider.py的內容:

[python]  view plain  copy
 
  1. # coding=utf-8  
  2. from scrapy.spider import Spider  
  3. from scrapy.http import Request  
  4. from scrapy.selector import Selector  
  5. from weibo.items import InformationItem,TweetsItem  
  6. import re  
  7. import requests  
  8. from bs4 import BeautifulSoup  
  9.   
  10.   
  11.   
  12. class Weibo(Spider):  
  13.     name = "weibospider"  
  14.     redis_key = 'weibospider:start_urls'  
  15.     #可以從多個用戶的關注列表中獲取這些用戶的關注對象信息和關注對象的微博信息  
  16.     start_urls = ['http://weibo.cn/0123456789/follow','http://weibo.cn/0123456789/follow']  
  17.     #如果通過用戶的分組獲取關注列表進行抓取數據,需要調整parse中如id和nextlink的多個參數  
  18.     #strat_urls = ['http://weibo.cn/attgroup/show?cat=user¤tPage=2&rl=3&next_cursor=20&previous_cursor=10&type=opening&uid=1771329897&gid=201104290187632788&page=1']  
  19.     url = 'http://weibo.cn'  
  20.     #group_url = 'http://weibo.cn/attgroup/show'  
  21.     #把已經獲取過的用戶ID提前加入Follow_ID中避免重復抓取  
  22.     Follow_ID = ['0123456789']  
  23.     TweetsID = []  
  24.   
  25.     def parse(self,response):  
  26.         #用戶關注者信息  
  27.         informationItems = InformationItem()  
  28.         selector = Selector(response)  
  29.   
  30.         print selector  
  31.         Followlist = selector.xpath('//tr/td[2]/a[2]/@href').extract()  
  32.         print "輸出關注人ID信息"  
  33.         print len(Followlist)  
  34.   
  35.         for each in Followlist:  
  36.             #選取href字符串中的id信息  
  37.             followId = each[(each.index("uid")+4):(each.index("rl")-1)]  
  38.             print followId  
  39.             follow_url = "http://weibo.cn/%s" % followId  
  40.             #通過篩選條件獲取需要的微博信息,此處為篩選原創帶圖的微博  
  41.             needed_url = "http://weibo.cn/%s/profile?hasori=1&haspic=1&endtime=20160822&advancedfilter=1&page=1" % followId  
  42.             print follow_url  
  43.             print needed_url  
  44.             #抓取過數據的用戶不再抓取:  
  45.             while followId not in self.Follow_ID:  
  46.                 yield Request(url=follow_url, meta={"item": informationItems, "ID": followId, "URL": follow_url}, callback=self.parse1)  
  47.                 yield Request(url=needed_url, callback=self.parse2)  
  48.                 self.Follow_ID.append(followId)  
  49.   
  50.         nextLink = selector.xpath('//div[@class="pa"]/form/div/a/@href').extract()  
  51.         #查找下一頁,有則循環  
  52.         if nextLink:  
  53.             nextLink = nextLink[0]  
  54.             print nextLink  
  55.             yield Request(self.url + nextLink, callback=self.parse)  
  56.         else:  
  57.             #沒有下一頁即獲取完關注人列表之后輸出列表的全部ID  
  58.             print self.Follow_ID  
  59.             #yield informationItems  
  60.   
  61.     def parse1(self, response):  
  62.         """ 通過ID訪問關注者信息 """  
  63.         #通過meta把parse中的對象變量傳遞過來  
  64.         informationItems = response.meta["item"]  
  65.         informationItems['_id'] = response.meta["ID"]  
  66.         informationItems['HomePage'] = response.meta["URL"]  
  67.         selector = Selector(response)  
  68.         #info = ";".join(selector.xpath('//div[@class="ut"]/text()').extract())  # 獲取標簽里的所有text()  
  69.         info = selector.xpath('//div[@class="ut"]/span[@class="ctt"]/text()').extract()  
  70.         #用/分開把列表中的各個元素便於區別不同的信息  
  71.         allinfo = '  /  '.join(info)  
  72.         try:  
  73.             #exceptions.TypeError: expected string or buffer  
  74.             informationItems['Info'] = allinfo  
  75.         except:  
  76.             pass  
  77.         #text2 = selector.xpath('body/div[@class="u"]/div[@class="tip2"]').extract()  
  78.         num_tweets = selector.xpath('body/div[@class="u"]/div[@class="tip2"]/span/text()').extract()  # 微博數  
  79.         num_follows = selector.xpath('body/div[@class="u"]/div[@class="tip2"]/a[1]/text()').extract()  # 關注數  
  80.         num_fans = selector.xpath('body/div[@class="u"]/div[@class="tip2"]/a[2]/text()').extract()  # 粉絲數  
  81.         #選取'[' ']'之間的內容  
  82.         if num_tweets:  
  83.             informationItems["Num_Tweets"] = (num_tweets[0])[((num_tweets[0]).index("[")+1):((num_tweets[0]).index("]"))]  
  84.         if num_follows:  
  85.             informationItems["Num_Follows"] = (num_follows[0])[((num_follows[0]).index("[")+1):((num_follows[0]).index("]"))]  
  86.         if num_fans:  
  87.             informationItems["Num_Fans"] = (num_fans[0])[((num_fans[0]).index("[")+1):((num_fans[0]).index("]"))]  
  88.   
  89.         yield informationItems  
  90.   
  91.     #獲取關注人的微博內容相關信息  
  92.     def parse2(self, response):  
  93.   
  94.         selector = Selector(response)  
  95.         tweetitems = TweetsItem()  
  96.         #可以直接用request的meta傳遞ID過來更方便  
  97.         IDhref = selector.xpath('//div[@class="u"]/div[@class="tip2"]/a[1]/@href').extract()  
  98.         ID = (IDhref[0])[1:11]  
  99.         Tweets = selector.xpath('//div[@class="c"]')  
  100.   
  101.   
  102.         # 跟parse1稍有不同,通過for循環尋找需要的對象  
  103.         for eachtweet in Tweets:  
  104.             #獲取每條微博唯一id標識  
  105.             mark_id = eachtweet.xpath('@id').extract()  
  106.             print mark_id  
  107.             #當id不為空的時候加入到微博獲取列表  
  108.             if mark_id:  
  109.                 #去重操作,對於已經獲取過的微博不再獲取  
  110.                 while mark_id not in self.TweetsID:  
  111.                     content = eachtweet.xpath('div/span[@class="ctt"]/text()').extract()  
  112.                     timelocation = eachtweet.xpath('div[2]/span[@class="ct"]/text()').extract()  
  113.                     pic_url = eachtweet.xpath('div[2]/a[2]/@href').extract()  
  114.                     like = eachtweet.xpath('div[2]/a[3]/text()').extract()  
  115.                     transfer = eachtweet.xpath('div[2]/a[4]/text()').extract()  
  116.                     comment = eachtweet.xpath('div[2]/a[5]/text()').extract()  
  117.   
  118.                     tweetitems['_id'] = ID  
  119.                     #把列表元素連接且轉存成字符串  
  120.                     allcontents = ''.join(content)  
  121.                     #內容可能為空 需要先判定  
  122.                     if allcontents:  
  123.                         tweetitems['Content'] = allcontents  
  124.                     else:  
  125.                         pass  
  126.                     if timelocation:  
  127.                         tweetitems['Time_Location'] = timelocation[0]  
  128.                     if pic_url:  
  129.                         tweetitems['Pic_Url'] = pic_url[0]  
  130.                     # 返回字符串中'[' ']'里的內容  
  131.                     if like:  
  132.                         tweetitems['Like'] = (like[0])[((like[0]).index("[")+1):((like[0]).index("]"))]  
  133.                     if transfer:  
  134.                         tweetitems['Transfer'] = (transfer[0])[((transfer[0]).index("[")+1):((transfer[0]).index("]"))]  
  135.                     if comment:  
  136.                         tweetitems['Comment'] = (comment[0])[((comment[0]).index("[")+1):((comment[0]).index("]"))]  
  137.                     #把已經抓取過的微博id存入列表  
  138.                     self.TweetsID.append(mark_id)  
  139.                     yield tweetitems  
  140.             else:  
  141.                 #如果selector語句找不到id 查看當前查詢語句的狀態  
  142.                 print eachtweet  
  143.   
  144.         tweet_nextLink = selector.xpath('//div[@class="pa"]/form/div/a/@href').extract()  
  145.         if tweet_nextLink:  
  146.             tweet_nextLink = tweet_nextLink[0]  
  147.             print tweet_nextLink  
  148.             yield Request(self.url + tweet_nextLink, callback=self.parse2)  

每個微博用戶都有唯一的標識uid,此uid是獲取需要對象的關鍵。修改start_url里面的ID(0123456789),比如換成留幾手的ID(1761179351),即把地址換成你想獲取的用戶的關注人列表的信息,可以對多個用戶的關注列表用redis_keyf方式進行分布式操作。內容比較多就不一一介紹,代碼不理解的可以留言探討,本人也是模仿着別人的框架寫出來的代碼,不是科班出身,代碼寫的比較渣渣,大神可以幫忙指點一二。
 

3、獲取cookies模擬登陸微博:

[python]  view plain  copy
 
  1. # encoding=utf-8  
  2.   
  3. import requests  
  4. from selenium import webdriver  
  5. import time  
  6. from PIL import Image  
  7. import urllib2  
  8. from bs4 import BeautifulSoup  
  9. import re  
  10. import urllib  
  11.   
  12.   
  13. #多點賬號防止被和諧  
  14.   
  15. myAccount = [  
  16.     {'no': 'XXXXXXXXXX', 'psw': 'XXXXXXXXX'},  
  17.     {'no': 'XXXXXXXX', 'psw': 'XXXXXXX'},  
  18.     {'no': 'XXXXXX', 'psw': 'XXXXXXX'}  
  19. ]  
  20.   
  21. headers={  
  22.     "Host":"login.weibo.cn",  
  23.     "User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0",  
  24.     "Accept":'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',  
  25.     "Accept-Language":"zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3",  
  26.     "Accept-Encoding":"gzip, deflate",  
  27.     "Connection":"keep-alive"  
  28. }  
  29.   
  30. # 獲取驗證碼等相關登錄信息  
  31. def get_captchainfo(loginURL):  
  32.     html = requests.get(loginURL).content  
  33.     bs = BeautifulSoup(html)  
  34.     #print bs  
  35.     #注意通過bs.select元素尋找對象,返回的是列表對象  
  36.     password_name = (bs.select('input[type="password"]'))[0].get('name')  
  37.     vk = (bs.select('input[name="vk"]'))[0].get('value')  
  38.     capId = (bs.select('input[name="capId"]'))[0].get('value')  
  39.     print password_name,vk,capId  
  40.     try:  
  41.         captcha_img = bs.find("img", src=re.compile('http://weibo.cn/interface/f/ttt/captcha/')).get('src')  
  42.         print captcha_img  
  43.         #captchaid可以從驗證碼圖片地址中直接截取獲得  
  44.         urllib.urlretrieve(captcha_img, 'captcha.jpg')  
  45.         print "captcha download success!"  
  46.         captcha_input = input("please input the captcha\n>")  
  47.     except:  
  48.         return None  
  49.   
  50.     return (captcha_input,password_name,vk,capId)  
  51.   
  52.   
  53.   
  54. def getCookies(weibo):  
  55.     """ 獲取Cookies """  
  56.     cookies = []  
  57.     loginURL = 'http://login.weibo.cn/login/'  
  58.     for elem in weibo:  
  59.         account = elem['no']  
  60.         password = elem['psw']  
  61.         captcha = get_captchainfo(loginURL)  
  62.         if captcha[0] is None:  
  63.             #不需要驗證碼時的表單,微博移動網頁版都要驗證碼,此處可以忽略  
  64.             postData = {  
  65.                     "source": "None",  
  66.                     "redir": "http://weibo.cn/",  
  67.                     "mobile": account,  
  68.                     "password": password,  
  69.                     "login": "登錄",  
  70.             }  
  71.         else:  
  72.             #需要驗證碼時的表單  
  73.             print "提交表單數據"  
  74.             postData = {  
  75.                     "mobile": account,  
  76.                     captcha[1]: password,  
  77.                     "code": captcha[0],  
  78.                     "remember":"on",  
  79.                     "backurl": "http://weibo.cn/",  
  80.                     "backtitle":u'微博',  
  81.                     "tryCount":"",  
  82.                     "vk": captcha[2],  
  83.                     "capId": captcha[3],  
  84.                     "submit": u'登錄',  
  85.             }  
  86.         print postData  
  87.         session = requests.Session()  
  88.         r = session.post(loginURL, data=postData, headers=headers)  
  89.         #判斷post過后是否跳轉頁面  
  90.         #time.sleep(2)  
  91.         print r.url  
  92.         if r.url == 'http://weibo.cn/?PHPSESSID=&vt=1'or 'http://weibo.cn/?PHPSESSID=&vt=4':  
  93.             ceshihtml = requests.get(r.url).content  
  94.             print ceshihtml  
  95.             print 'Login successfully!!!'  
  96.             cookie = session.cookies.get_dict()  
  97.             cookies.append(cookie)  
  98.         else:  
  99.             print "login failed!"  
  100.   
  101.     return cookies  
  102.   
  103. ''''' 
  104. #通過selenium driver方式獲取cookie 
  105. def getcookieByDriver(weibo): 
  106.     driver = webdriver.Firefox() 
  107.     driver.maximize_window() 
  108.     cookies = [] 
  109.     for elem in weibo: 
  110.         account = elem['no'] 
  111.         password = elem['psw'] 
  112.         driver.get("http://login.weibo.cn/login/") 
  113.         elem_user = driver.find_element_by_name("mobile") 
  114.         elem_user.send_keys(account)  # 用戶名 
  115.         #微博的password有加后綴, 
  116.         elem_pwd = driver.find_element_by_name("password_XXXX") 
  117.         elem_pwd.send_keys(password)  # 密碼 
  118.         time.sleep(10) 
  119.         #手動輸驗證碼時間 
  120.         elem_sub = driver.find_element_by_name("submit") 
  121.         elem_sub.click()  # 點擊登陸 
  122.         time.sleep(2) 
  123.         weibo_cookies = driver.get_cookies() 
  124.         #cookie = [item["name"] + "=" + item["value"] for item in douban_cookies] 
  125.         #cookiestr = '; '.join(item for item in cookie) 
  126.         cookies.append(weibo_cookies) 
  127.     return cookies 
  128. '''  
  129.   
  130. cookies = getCookies(myAccount)  
  131. #cookies = getcookieByDriver(myAccount)  
  132. print "Get Cookies Finish!( Num:%d)" % len(cookies)  

在myAcount中輸入你自己擁有的微博賬號密碼,就可以模擬登陸微博啦:
這里有兩種方式:
【1】模擬瀏覽器提交表單登陸(推薦)
【2】通過selenium WebDriver 方式登陸
驗證碼暫時還是先手動輸一下吧,還沒有找到快速有效的方式破解。
反正只要拿到cookie保存下來就可以進行抓取操作啦。
 

4、數據管道pipeline存入MySQL數據庫:

[python]  view plain  copy
 
  1. # -*- coding: utf-8 -*-  
  2. import MySQLdb  
  3. from items import InformationItem,TweetsItem  
  4.   
  5. DEBUG = True  
  6.   
  7. if DEBUG:  
  8.     dbuser = 'root'  
  9.     dbpass = '123456'  
  10.     dbname = 'tweetinfo'  
  11.     dbhost = '127.0.0.1'  
  12.     dbport = '3306'  
  13. else:  
  14.     dbuser = 'XXXXXXXX'  
  15.     dbpass = 'XXXXXXX'  
  16.     dbname = 'tweetinfo'  
  17.     dbhost = '127.0.0.1'  
  18.     dbport = '3306'  
  19.   
  20.   
  21. class MySQLStorePipeline(object):  
  22.     def __init__(self):  
  23.         self.conn = MySQLdb.connect(user=dbuser, passwd=dbpass, db=dbname, host=dbhost, charset="utf8",  
  24.                                     use_unicode=True)  
  25.         self.cursor = self.conn.cursor()  
  26.         #建立需要存儲數據的表  
  27.   
  28.         # 清空表(測試階段):  
  29.         self.cursor.execute("truncate table followinfo;")  
  30.         self.conn.commit()  
  31.         self.cursor.execute("truncate table tweets;")  
  32.         self.conn.commit()  
  33.   
  34.     def process_item(self, item, spider):  
  35.         #curTime = datetime.datetime.now()  
  36.         if isinstance(item, InformationItem):  
  37.             print "開始寫入關注者信息"  
  38.             try:  
  39.                 self.cursor.execute("""INSERT INTO followinfo (id, Info, Num_Tweets, Num_Follows, Num_Fans, HomePage) 
  40.                                 VALUES (%s, %s, %s, %s, %s, %s)""",  
  41.                                     (  
  42.                                         item['_id'].encode('utf-8'),  
  43.                                         item['Info'].encode('utf-8'),  
  44.                                         item['Num_Tweets'].encode('utf-8'),  
  45.                                         item['Num_Follows'].encode('utf-8'),  
  46.                                         item['Num_Fans'].encode('utf-8'),  
  47.                                         item['HomePage'].encode('utf-8'),  
  48.                                     )  
  49.                                     )  
  50.   
  51.                 self.conn.commit()  
  52.             except MySQLdb.Error, e:  
  53.                 print "Error %d: %s" % (e.args[0], e.args[1])  
  54.   
  55.         elif isinstance(item, TweetsItem):  
  56.             print "開始寫入微博信息"  
  57.             try:  
  58.                 self.cursor.execute("""INSERT INTO tweets (id, Contents, Time_Location, Pic_Url, Zan, Transfer, Comment) 
  59.                                 VALUES (%s, %s, %s, %s, %s, %s, %s)""",  
  60.                                     (  
  61.                                         item['_id'].encode('utf-8'),  
  62.                                         item['Content'].encode('utf-8'),  
  63.                                         item['Time_Location'].encode('utf-8'),  
  64.                                         item['Pic_Url'].encode('utf-8'),  
  65.                                         item['Like'].encode('utf-8'),  
  66.                                         item['Transfer'].encode('utf-8'),  
  67.                                         item['Comment'].encode('utf-8')  
  68.                                     )  
  69.                                     )  
  70.                 self.conn.commit()  
  71.   
  72.             except MySQLdb.Error, e:  
  73.                 print "出現錯誤"  
  74.                 print "Error %d: %s" % (e.args[0], e.args[1])  
  75.   
  76.         return item  

MySQL部署好之后只要輸入自己的用戶名密碼就可以存到數據庫當中去
因為我的創建表格沒有寫到pipeline中,就先自己建好數據庫和表格好了:
需要注意的是:為了讓mysql正常顯示中文,在建立數據庫的時候使用如下語句:
[sql]  view plain  copy
 
  1. CREATE DATABASE tweetinfo DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;  
數據庫目錄結構:
 
 
創建 表格followinfo
[sql]  view plain  copy
 
  1. CREATE TABLE `followinfo` (  
  2.     `No` INT(11) NOT NULL AUTO_INCREMENT,  
  3.     `id` VARCHAR(50) NULL DEFAULT NULL,  
  4.     `Info` VARCHAR(100) NOT NULL,  
  5.     `Num_Tweets` INT(10) NOT NULL,  
  6.     `Num_Follows` INT(10) NOT NULL,  
  7.     `Num_Fans` INT(10) NOT NULL,  
  8.     `HomePage` VARCHAR(50) NOT NULL,  
  9.     PRIMARY KEY (`No`)  
  10. )  
  11. COLLATE='utf8_general_ci'  
  12. ENGINE=MyISAM  
  13. AUTO_INCREMENT=5  
  14. ;  


創建表格tweets
[sql]  view plain  copy
 
  1. CREATE TABLE `tweets` (  
  2.     `No` INT(11) NOT NULL AUTO_INCREMENT,  
  3.     `id` VARCHAR(20) NOT NULL,  
  4.     `Contents` VARCHAR(300) NULL DEFAULT NULL,  
  5.     `Time_Location` VARCHAR(50) NOT NULL,  
  6.     `Pic_Url` VARCHAR(100) NULL DEFAULT NULL,  
  7.     `Zan` INT(10) NOT NULL,  
  8.     `Transfer` INT(10) NOT NULL,  
  9.     `Comment` INT(10) NOT NULL,  
  10.     PRIMARY KEY (`No`)  
  11. )  
  12. COLLATE='utf8_general_ci'  
  13. ENGINE=MyISAM  
  14. AUTO_INCREMENT=944  
  15. ;  

5、中間組建middleware:

[python]  view plain  copy
 
  1. # encoding=utf-8  
  2. import random  
  3. from cookies import cookies  
  4. from user_agents import agents  
  5.   
  6.   
  7. class UserAgentMiddleware(object):  
  8.     """ 換User-Agent """  
  9.   
  10.     def process_request(self, request, spider):  
  11.         agent = random.choice(agents)  
  12.         request.headers["User-Agent"] = agent  
  13.   
  14.   
  15. class CookiesMiddleware(object):  
  16.     """ 換Cookie """  
  17.   
  18.     def process_request(self, request, spider):  
  19.         cookie = random.choice(cookies)  
  20.         request.cookies = cookie  



 
          
 

6、設置相關settings:

[python]  view plain  copy
 
  1. # coding=utf-8  
  2.   
  3. BOT_NAME = 'weibo'  
  4.   
  5. SPIDER_MODULES = ['weibo.spiders']  
  6. NEWSPIDER_MODULE = 'weibo.spiders'  
  7.   
  8. USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.54 Safari/536.5'  
  9.   
  10. ''''' 
  11. #把數據存到路徑中的CSV文件中去 
  12. FEED_URI = u'file:///G:/MovieData/followinfo.csv' 
  13. FEED_FORMAT = 'CSV' 
  14. '''  
  15.   
  16. DOWNLOADER_MIDDLEWARES = {  
  17.     "weibo.middleware.UserAgentMiddleware": 401,  
  18.     "weibo.middleware.CookiesMiddleware": 402,  
  19. }  
  20.   
  21.   
  22. ITEM_PIPELINES = {  
  23.     #'weather2.pipelines.Weather2Pipeline': 300,  
  24.     'weibo.pipelines.MySQLStorePipeline': 300,  
  25. }  
  26.   
  27.   
  28. DOWNLOAD_DELAY = 2  # 下載器間隔時間  
  29.   
  30. # Crawl responsibly by identifying yourself (and your website) on the user-agent  
  31. #USER_AGENT = 'doubanmovie (+http://www.yourdomain.com)'  
 
數據爬取效果展示:

四、總結:

1、學習了解scrapy框架寫代碼熟悉數據流的流程收獲還是很多的。
2、感覺不是太復雜的網站應該都是可以抓的。形成了自己的一套系統知識體系,具體情況具體分析吧。
3、驗證碼這塊簡單的還能識別,復雜的可能得稍微用點深度學習了,識別率很一般,暫時還是人工輸入吧。
4、爬蟲只是很入門的技術,后續需要學的東西還好多。
額,看到這里也是不容易,說了這么多,關鍵還是直接打包工程源碼: 點擊打開鏈接
 
 
轉載:http://blog.csdn.net/zengsl233/article/details/52294760


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM