用scrapy循環爬取京東數據導入Mysql

    感覺網上用scrapy爬京東數據的文章挺多的,但是我還是想自己寫一遍吧。

京東是有反爬機制的,所以我用到用戶代理、僞裝成瀏覽器。

爬取數據是京東商城的手機信息 URL:https://list.jd.com/list.html?cat=9987,653,655&page=1

大概是9000多條數據,不在列表之內的商品沒有算在內。

我遇到的問題:

1、用戶代理最好是用方法(use_proxy)封裝起來,因爲自己之前就是把代碼直接寫在parse下,遇到not enough values to unpack的問題,我實在不知道錯誤出在哪一句,就每句代碼之後print,發現問題出在urlopen(),但是我反覆試、查網上,也沒發現錯誤在哪,寫成方法就解決了,現在想來可能是因爲parse方法是處理respose。

2、在把數據導入mysql之前,我先試着把數據導入到文件中,但是在導入中,發現x.txt的大小一直是0kb,1kb在變,沒有增長,想想應該是覆蓋了,本來是認爲自己fh.close()寫的位置不對,後來突然想到

fh = open("D:/pythonlianxi/result/4.txt", "w")寫錯了,應該要把'w'變成'a'。

3、導入數據庫,碰到的問題主要是中文編碼問題,要先打開mysql,  show variables like '%char%';查看數據庫的字符集編碼形式,用對應的形式,比如我自己是utf8,用gbk就不好使。另外,在寫連接mysql時 charset='utf8'不要忘記。

conn = pymysql.connect(host="127.0.0.1", user="root", passwd="root", db="jingdong", charset="utf8")

import scrapy
from scrapy.http import Request
from jingdong.items import JingdongItem
import re
import urllib.error
import urllib.request
import pymysql
class JdSpider(scrapy.Spider):
    name = 'jd'
    allowed_domains = ['jd.com']
    #start_urls = ['http://jd.com/']
    header = {"User-Agent":"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36"}
    #fh = open("D:/pythonlianxi/result/4.txt", "w")
    def start_requests(self):
        return [Request("https://list.jd.com/list.html?cat=9987,653,655&page=1",callback=self.parse,headers=self.header,meta={"cookiejar":1})]
    def use_proxy(self,proxy_addr,url):
        try:
            req=urllib.request.Request(url)
            req.add_header("User-Agent","Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36")
            proxy = urllib.request.ProxyHandler({"http": proxy_addr})
            opener = urllib.request.build_opener(proxy, urllib.request.HTTPHandler)
            urllib.request.install_opener(opener)
            data=urllib.request.urlopen(req).read().decode("utf-8","ignore")
            return data
        except urllib.error.URLError as e:
            if hasattr(e,"code"):
                print(e.code)
            if hasattr(e,"reason"):
                print(e.reason)
        except Exception as e:
            print(str(e))


    def parse(self, response):
        item=JingdongItem()
        proxy_addr = "61.135.217.7:80"
        try:
            item["title"]=response.xpath("//div[@class='p-name']/a[@target='_blank']/em/text()").extract()
            item["pricesku"] =response.xpath("//li[@class='gl-item']/div/@data-sku").extract()

            for j in range(2,166):
                url="https://list.jd.com/list.html?cat=9987,653,655&page="+str(j)
                print(j)
                #yield item
                yield Request(url)
            pricepat = '"p":"(.*?)"'
            personpat = '"CommentCountStr":"(.*?)",'
            print("2k")
            #fh = open("D:/pythonlianxi/result/5.txt", "a")
            conn = pymysql.connect(host="127.0.0.1", user="root", passwd="root", db="jingdong", charset="utf8")
            
            for i in range(0,len(item["pricesku"])):
                priceurl="https://p.3.cn/prices/mgets?&ext=11000000&pin=&type=1&area=1_72_4137_0&skuIds="+item["pricesku"][i]
                personurl = "https://club.jd.com/comment/productCommentSummaries.action?referenceIds=" + item["pricesku"][i]
                pricedata=self.use_proxy(proxy_addr,priceurl)
                price=re.compile(pricepat).findall(pricedata)
                persondata = self.use_proxy(proxy_addr,personurl)
                person = re.compile(personpat).findall(persondata)
         
                title=item["title"][i]
                print(title)
                price1=float(price[0])
                #print(price1)
                person1=person[0]
                #fh.write(tile+"\n"+price+"\n"+person+"\n")
                cursor = conn.cursor()
                sql = "insert into jd(title,price,person) values(%s,%s,%s);"
                params=(title,price1,person1)
                print("4")
                cursor.execute(sql,params)
                conn.commit()

            #fh.close()
           conn.close()
            return item
        except Exception as e:
            print(str(e))


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章