對urllib、requests、scrapy的總結


學習了爬蟲有一段時間了,是時候對urllib、requests、scrapy三者的基本用法做一次總結了。

1、urllib模塊

1.1、添加UA
 1 import urllib.request
 2 
 3 # User-Agent是爬蟲與反爬蟲的第一步
 4 ua_headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) '
 5                             'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari/537.36'}
 6 # 通過urllib2.Request()方法構造一個請求對象
 7 request = urllib.request.Request('http://www.baidu.com/', headers=ua_headers)
 8 response = urllib.request.urlopen(request)
 9 html = response.read()
10 
11 print(html)

 

1.2、ProxyHandler處理器(代理設置)

需要注意的是,urlopen()方法不支持代理,也不支持獲取、存儲cookie,所以要為我們的urllib設置代理或者進行cookie的操作的話需要先自定義opener()方法

 1 import urllib.request
 2 
 3 
 4 # 構建一個HTTPHandler 處理器對象,支持處理HTTP請求
 5 http_handler = urllib.request.HTTPHandler()
 6 
 7 # 構建一個HTTPHandler 處理器對象,支持處理HTTPS請求
 8 # http_handler = urllib2.request.HTTPSHandler()
 9 
10 # 調用urllib.request.build_opener()方法,創建支持處理HTTP請求的opener對象
11 opener = urllib.request.build_opener(http_handler)
12 
13 # 構建 Request請求
14 request = urllib.request.Request("http://www.baidu.com/")
15 
16 
17 # 調用自定義opener對象的open()方法,發送request請求
18 response = opener.open(request)
19 
20 # 獲取服務器響應內容
21 print(response.read())

 這個時候在來添加代理到urllib中

 1 import urllib.request
 2 
 3 # 構建了兩個代理Handler,一個有代理IP,一個沒有代理IP
 4 httpproxy_handler = urllib.request.ProxyHandler({"http": "124.88.67.81:80"})    # 傳入的是字典
 5 nullproxy_handler = urllib.request.ProxyHandler({})
 6 
 7 proxySwitch = True #定義一個代理開關
 8 
 9 # 通過 urllib2.build_opener()方法使用這些代理Handler對象,創建自定義opener對象
10 # 根據代理開關是否打開,使用不同的代理模式
11 if proxySwitch:
12     opener = urllib.request.build_opener(httpproxy_handler)
13 else:
14     opener = urllib.request.build_opener(nullproxy_handler)
15 
16 request = urllib.request.Request("http://www.baidu.com/")
17 
18 # 1. 如果這么寫,只有使用opener.open()方法發送請求才使用自定義的代理,而urlopen()則不使用自定義代理。
19 response = opener.open(request)
20 
21 # 2. 如果這么寫,就是將opener應用到全局,之后所有的,不管是opener.open()還是urlopen() 發送請求,都將使用自定義代理。
22 # urllib2.install_opener(opener)
23 # response = urlopen(request)
24 
25 print(response.read())
 1.3、HTTPCookieProcessor處理器(urllib添加cookie)
 1 import urllib.request
 2 import http.cookiejar as cj  # python3中將cookielib改成了http.cookiejar
 3 
 4 # 構建一個CookieJar對象實例來保存cookie
 5 cookiejar = cj.CookieJar()
 6 
 7 # 使用HTTPCookieProcessor()來創建cookie處理器對象,參數為CookieJar()對象
 8 handler=urllib.request.HTTPCookieProcessor(cookiejar)
 9 
10 # 通過 build_opener() 來構建opener
11 opener = urllib.request.build_opener(handler)
12 
13 # 4. 以get方法訪問頁面,訪問之后會自動保存cookie到cookiejar中
14 opener.open("http://www.baidu.com")
15 
16 # 可以按標准格式將保存的Cookie打印出來
17 cookieStr = ""
18 for item in cookiejar:
19     cookieStr = cookieStr + item.name + "=" + item.value + ";"
20 
21 # 舍去最后一位的分號
22 print(cookieStr[:-1])

 可以看到urllib在添加代理,處理cookie的時候,需要做額外的配置,顯得冗余且不好理解,別擔心用requests

2、requests模塊

2.1、添加UA
 1 import requests
 2 
 3 kw = {'wd':'長城'}
 4 
 5 headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"}
 6 
 7 # params 接收一個字典或者字符串的查詢參數,字典類型自動轉換為url編碼,不需要urlencode()
 8 response = requests.get("http://www.baidu.com/s?", params = kw, headers = headers)
 9 
10 # 查看響應內容,response.text 返回的是Unicode格式的數據
11 print(response.text)
12 
13 # 查看響應內容,response.content返回的字節流數據
14 print(respones.content)
15 
16 # 查看完整url地址
17 print(response.url)
18 
19 # 查看響應頭部字符編碼
20 print(response.encoding)
21 
22 # 查看響應碼
23 print(response.status_code)
2.2、設置代理
mport requests

# 根據協議類型,選擇不同的代理
proxies = {
  "http": "http://12.34.56.79:9527",
  "https": "http://12.34.56.79:9527",
}

response = requests.get("http://www.baidu.com", proxies = proxies)
print(response.text)
2.3、直接獲取到HTTP-Cookie
 1 import requests
 2 
 3 response = requests.get("http://www.baidu.com/")
 4 
 5 # 7. 返回CookieJar對象:
 6 cookie_jar = response.cookies
 7 
 8 # 8. 將CookieJar轉為字典(兩種實現方式):
 9 # cookie_dict = requests.utils.dict_from_cookiejar(cookie_jar)
10 cookie_dict = response.cookies.get_dict()
11 
12 print(cookie_jar)
13 
14 print(cookie_dict)

案例通過cookie訪問抽屜的個人中心

 1 import requests
 2 
 3 cookie = {
 4     "gpsd": "b3c059bef6faa0fd56282xxxxxx",
 5     "JSESSIONID": "aaaTto6SLmxxxxxxxx",
 6     "gpid": "22bb5d4a3f824de78ad3d7fe7a0844f6",
 7     "gdxidpyhxdE": "M%2FOPyR5HMhg2qRDg2JQh9Z2KqygiCEXUUqpe0aqcwnTa%5CmsjKCoHoRRdnjJQAiCUcaAdEDrfiaKCP9ux7Sm2p6d69R24JWVPnHx0eHXgdo36PAY%2BD1BaTE8VJVw%2FDyImCiDbTRpdYL%2BXWArApjKJ31hgGTas1sGXOIdfAz0odXPdPDTg%3A1548427514478",
 8     " _9755xjdesxxd_": "32",
 9     "YD00000980905869%3AWM_NI": "zcykmdAFAGI4wEjxR%2BvX5ORpNMHi27FQebIhsdcSKxDk7TDy2y4kt13hjn4jV7ekyTlc%2BmR7Bs4a6DoM1eHXzS%2FgXa68mylIFXNyQd7Pjr%2FP2RvJSYwNTqwWgKcBsoRFSk0%3D" ,
10     "YD00000980905869%3AWM_NIKE": "9ca17ae2e6ffcda170e2e6eed7c16f9c95aeb1b33d86b88ba2c15f979a9bbbbb648a8fb6acd065a1bbbe8eeb2af0fea7c3b92ababdb78cf070839a8fa8cc40b59ba699d121b688fbb0d17c8e93888ab13d868fab83cc64b1bcadb4ca7xxxxx773f2a7fxx76296e9ab8cfc60b0bde58ed13d82xx86cb54ba8de188db6bf6e8a39aef438688829ad470f590a693ae5cf28ebaabd253b5929c92f65da595ada3f265929a9d8cb337e2a3",
11     "YD00000980905869%3AWM_TID": "zJgV%2FKPggm9BFUxxplJBzLdoNer3x",
12 }
13 headers = {
14     "User-agent": "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
15                   "Chrome/71.0.3578.98 Safari/537.36"
16 }
17 response = requests.get("https://dig.chouti.com/user/link/saved/1", cookies=cookie, headers=headers)
18 
19 print(response.text)

代碼中的cookie做了處理詳細的以自身為准。

更多關於requests的用法參考官方文檔,以及以后更的博客內容。我在這里只是展示下對比,方便記憶。

http://docs.python-requests.org/zh_CN/latest/user/quickstart.html#cookie

3、scrapy框架

scrapy是爬蟲的框架,框架操作起來相較於模塊就更加的復雜。

3.1、scrapy添加UA

在scrapy中添加User-agent的地方有很多,我一一的列出來:

1)直接寫在spider中

當然了上面的這種需要在每一次的Request中加上headers=self.headers操作,這樣寫起來相當麻煩。可以采用另外的方式來進行。

2)直接寫在settings.py中

USER_AGENT = 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.22 \
              Safari/537.36 SE 2.X MetaSr 1.0'

 或者

DEFAULT_REQUEST_HEADERS = {
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
    'Accept-Language': 'en',
    "authority": " www.dangdang.com",
    "method": "GET",
    "path": "/",
    "scheme": "http",
    "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
    "accept-encoding": 'gzip, deflate, br',
    "accept-language": 'en-US,en;q=0.9',
    "referer": None,
    "upgrade-insecure-requests": 1,
    "User-Agent": 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.22 \
                      Safari/537.36 SE 2.X MetaSr 1.0'
}
寫在DEFAULT_REQUEST_HEADERS的User-Ahent也需要每次都在Request的時候加上headers = DEFAULT_REQUEST_HEADERS,當然了上面說的兩種添加UA的方式都是在目標網站沒有做反爬蟲的前提下進行的。如果限制了UA,上面
的兩種做法,在你爬取了一定量數據的時候就很可能你的爬蟲就會被BAN。
2)寫在中間件里或者寫在一個單獨的文件中,實現隨機獲取UA
這種做法你在網上一搜一大堆,具體的過程我不想說了,直接上代碼。
middlewares.py
from fake_useragent import UserAgent


class RandomUserAgentMiddleWare(object):
    # 隨機更換user-agent
    def __init__(self, crawler):
        super(RandomUserAgentMiddleWare, self).__init__()
        # self.user_agent_list = crawler.settings.get("user_agent_list", [])
        self.user_agent = UserAgent()
        self.user_agent_type = crawler.settings.get("RANDOM_UA_TYPE", "random")

    @classmethod
    def from_crawler(cls, crawler):
        return cls(crawler)

    def process_request(self, request, spider):
        def get_user_agent():
            """字符串取類中的方法"""
            return getattr(self.user_agent, self.user_agent_type)

        # ua = get_user_agent()
        request.headers.setdefault('User-Agent', get_user_agent())
settings.py
RANDOM_UA_TYPE = "random"    #隨機生成UA的類型

...
DOWNLOADER_MIDDLEWARES = { 'ArticleSpider.middlewares.RandomUserAgentMiddleWare': 543, 'scrapy.contrib.downloadermiddleware.useragent.UserAgentMiddleware': None, # 加上這段 }
還有就是以文件的方式存儲UA然后random.choice()去取,懶得貼代碼了。
3.2、scrapy設置代理IP

 pass

3.3、scrapy添加cookies

 在scrapy中添加cookies要先從settings.py這里說起

# Disable cookies (enabled by default)
# COOKIES_ENABLED = False

 默認是啟用了cookiesmiddleware,可以看一下cookiesmiddleware的源碼

  

如果把  COOKIES_ENABLED = False 的注釋取消掉,直接執行紅框的代碼。那么就無法實例化這個類,無法實例化類就不走__init__(),后面的代碼就不走了,也就是說關閉了cookiesmiddleware。經常在一些博客上看見這樣的騷操作 COOKIES_ENABLED = True  這不是多此一舉嗎?


 添加cookies該怎么做啦?

具體參考我的這篇博客scrapy-cookie部分

當然添加cookies還可以這樣寫,直接寫在Request()請求中確保注釋掉  # COOKIES_ENABLED = False

    def start_requests(self):
        yield Request(url=self.start_urls[0],
                      cookies={
                          "gpsd": "e8cf1xxxx0ab4c44",
                          "JSESSIONID": "aaxxNFteIw",
                          "gpid": "xxx26264038c5583",
                          "gdxidpyhxdE": "yweI%2F%2xxxCCNPrGT0zAgxxKnupVwxxxUe%2BuG5wAOxzw7kRxxx6xxxx2FMJ%2BvNcJHDaAxEUxxxm4EIt028fj8Gokxxxx293023973",
                          "_9755xjdesxxd_": "32",
                          "puid": "xxxxxx",
                          "puid": "xxx8",
                      },
                      callback=self.parse)

 也可以寫在中間件里確保注釋掉  # COOKIES_ENABLED = False

class TestCookieDownloaderMiddleware(object):
    @classmethod
    def from_crawler(cls, crawler):
        s = cls()
        return s

    def process_request(self, request, spider):
        cookie_dict = {
            "gpsd": "e8cf1dd46xxx966e0ab4c44",
            "JSESSIONID": "aaa8hxxxNFteIw",
            "gpid": "c36f5xx0d4xx8c5583",
            "gdxidpyhxdE": "yweI%2F%2F%5CCNPrGT0xxxxxOlWiDSOslTJTOq2vMUe%2BuG5wAOxzw7kR%2FxxxxxAxEUCSITyYb87Mhxr8TxxxT3MQ4m4EIt028fj8Gok%3A1550293023973",
            "_9755xjdesxxd_": "32",
            "puid": "cdxxxx79005045",
            "puid": "dxx62d9xxxxxf4c8",
        }
        request.cookies = cookie_dict

    def process_response(self, request, response, spider):
        return response

 這樣的話每一次你的Request請求都會攜帶着寫好的cookies,可以跳過一些網站的登錄直接訪問內容,當然了在實際開發中不可能讓你這么簡單就跳過登陸了,以淘寶為例一個cookies最多讓你訪問20個頁面,這個時候cookies池就很關鍵了,關於cookie池的建立先跳過,后面再來填坑。

 


免責聲明!

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



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