(确定了cookie能满足我们的需求,才能确保项目的可行性)
1、安装scrapy框架(直接pip安装就行)
pip install scrapy
2、创立项目对应爬虫
>cd 相应目录
相应目录>scrapy startproject taobao
相应目录>cd taobao2
相应目录\taobao>scrapy genspider nanzhuang taobao.com
3、修改爬虫文件,使用cookie进入搜索页面
在知道项目目标之后查找元素
其中蓝色框中的各个小项就是我们的目标。
我们手动点开这些小项后却发现需要登陆(未登录状态)
接着手动登录,登录后刷新获取网页的cookie.
获取cookie后将其写入爬虫的setting文件中
然后尝试修改nanzhuang.py进行爬取
import scrapy
class XuexiSpider(scrapy.Spider):
name = 'xuexi'
allowed_domains = ['taobao.com']
start_urls = ['https://www.taobao.com/markets/nanzhuang/2017new']
def parse(self, response):
for it in response.xpath('//*[@id="sm-nav-2014"]/div[2]/div[2]/div/div[2]/dl'):
#使用xpath+for循环的模式遍历所有小项
for n in it.xpath('./dd'):
try:
li = n.xpath('./a/@href').extract()[0]
yield scrapy.Request(li,callback = self.parse_detail)
#将获取到的网址返回进行访问和解析
except:
pass
def parse_detail(self,response):
pass
运行一次爬虫试试
爬虫文件夹目录>scrapy crawl nanzhuang
如果结果为以下,说明你的cookie能让爬虫爬取相应页面
接着寻找我们需要的元素
方案一、用xpath直接获取价格,商品名称。但是发现用了js,而且获取不到正确的价格。所以被我pass掉了,你们可以尝试。
方案二、直接使用re
先检查网页源代码查找价格,商品名称。
回到爬虫文件进行修改
item.py:
import scrapy
class Taobao2Item(scrapy.Item):
# define the fields for your item here like:
title = scrapy.Field()
price = scrapy.Field()
nid = scrapy.Field()
nanzhuang.py:
import scrapy
import re
from taobao2.items import Taobao2Item
class NanzhuangSpider(scrapy.Spider):
name = 'nanzhuang'
allowed_domains = ['taobao.com']
start_urls = ['https://www.taobao.com/markets/nanzhuang/2017new?']
def parse(self, response):
for it in response.xpath('//*[@id="sm-nav-2014"]/div[2]/div[2]/div/div[2]/dl'):
for n in it.xpath('./dd'):
try:
li = n.xpath('./a/@href').extract()[0]
except:
pass
yield scrapy.Request(li,callback = self.parse_detail)
#先只返回一个网页,爬的快了容易被封号
def parse_detail(self,response):
item = Taobao2Item()
#使用re直接获取商品的价格,名称
title = re.findall('"raw_title":"(.*?)"',response.text)
price = re.findall('"view_price":"(.*?)"',response.text)
#nid对获取评论有用
nid = re.findall('"nid":"(.*?)"',response.text)
for i in range(0,59):
#分成60份,每一份中的价格和名称时对应的
item['title']=title[i]
item['price']=price[i]
这样我们就获取完商品的价格和名称了,接下来就差评论了
方案一、用selenium在详情页获取
(我没用这个方向,所以只说一下我的想法)
通过使用cookie进入url
url=https://item.taobao.com/item.htm?id=[刚刚获取的nid]&ns=1&abbucket=16
然后
driver.find_element_by_class_name(‘tb-tab-anchor’).click()
获取class_name=tb-rev-item的评论内容
方案二、寻找到获取评论的接口进行获取
进入商品详情页,点开评论详情,复制一条评论后在network中查找
但是当你直接点开这个对应的网址之后会发现你回到了我的淘宝页面
于是看它的header,发现和正常网页相比多了个Parameter的东西
此时再看它的网页,会发现第一个问号之后的内容都来自parameter
由此可以得出一个可能的结论,所有评论都来自https://rate.taobao.com/feedRateList.htm?,只是每次访问时携带的parameter不同导致返回的结果不同。对此修改我们的爬虫文件
只展示增加的代码
url="https://rate.tmall.com/list_detail_rate.htm"
header={
"cookie":你的cookie内容,
"referer":"https://detail.tmall.com/item.htm",
"user-agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 UBrowser/6.2.4098.3 Safari/537.37",
}
params={
#必带信息
"itemId":"", #商品id
"sellerId":"50010158",
"currentPage":"1", #页码
"order" : "1",
"callback":"jsonp2359",
}
params['itemId']=nid[i]
pinglun=[]
#fro it in range(1,1):# #选择爬取的评论页数范围
it=1
#但是爬多了或者快了就会被封号,如果没有对应的cookie池的话还是老实点吧
if (it):
params['currentPage']=str(it)
req=requests.get(url,params,headers=header).content.decode('utf-8')[12:-1]; #解码,并且去除str中影响json转换的字符(\n\rjsonp(...));
result=json.loads(req);
pl=re.findall(r'rateContent\': \'(.*?)\'',str(result))
print(pl)
pinglun.append(pl)
print (pinglun)
item['nid']=pinglun
time.sleep(0.7) #封号太狠,又没有cookie池,只能慢慢来
yield item
#别忘了import time
#import json
#import requests
接着尝试运行一边同时存储结果
scrapy crawl nanzhuang -o result.csv
正常(cookie也没过期)的话运行结果应该是这样的
这样的话在用cookie的情况下已经能完成爬取了,剩下的就是如何限制爬取速度防止一直被封。
我的思路一个个小项爬取(爬取完一个再爬取下一个),将所有小项的网址存入一个列表,每次返回的网址为列表[0],同时使用meta传参,每次解析时删去列表[0],如此反复
思路:1、使用selenium + chromedriver进行登录,方案一、破解webdriver使用demo(但是我并不会)附上原博链接:https://blog.csdn.net/taojian_/article/details/97758632
方案二、反复横跳,通过在淘宝,微博,淘宝直接跳跃,选取最薄弱的微博登录进行突破(也是我采用的方法)
2、使用其他插件或第三方库如pyppeteer等通过淘宝的验证
具体实施:selenium操作,,不用详细说了吧,你咋用微博快速登陆登录淘宝,selenium就咋来(但是微博账号和淘宝账号需要绑定,还有解除掉安全锁,这些在实施过程中自己操作就好,与爬虫关系不大)
好吧,我就是犯懒了,先贴代码为敬,细节写在后面了
from selenium import webdriver
from selenium.webdriver import ChromeOptions
import json
import time
import requests
from PIL import Image
import pytesseract
from io import BytesIO
def yanzhengma(url):
#识别验证码
r = requests.get(url, headers=headers) #请求验证码图片链接
im = Image.open(BytesIO(r.content)) #直接读取bytes数据,生成图片对象
width, height = im.size
#获取图片中的颜色,返回列表[(counts, color)...]
color_info = im.getcolors(width*height)
sort_color = sorted(color_info, key=lambda x: x[0], reverse=True)
#将背景全部改为白色, 提取出字,每张图片一个字
char_dict = {
}
for i in range(1, 6):
start_x = 0
im2 = Image.new('RGB', im.size, (255, 255, 255))
for x in range(im.size[0]):
for y in range(im.size[1]):
if im.getpixel((x, y)) == sort_color[i][1]:
im2.putpixel((x, y), (0, 0, 0))
if not start_x:
start_x = x #标记每个字符的起始位置,用于最后字符串的排序
else:
im2.putpixel((x, y), (255, 255, 255))
char = pytesseract.image_to_string(im2,config='--psm 10')
char_dict[start_x] = char
code = ''.join([item[1] for item in sorted(char_dict.items(), key=lambda i:i[0])])
return code
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'}
option = ChromeOptions()
option.add_experimental_option('excludeSwitches', ['enable-automation'])
b = webdriver.Chrome(options=option)
b.get('https://login.taobao.com/member/login.jhtml')
b.find_element_by_class_name("weibo-login").click()
#转到微博登录界面
b.find_element_by_name('username').send_keys('yourid')#输入你的微博账号
b.find_element_by_name('password').send_keys('yourpassword')#输入你的微博密码
b.find_element_by_class_name('W_btn_g').click()#登录按钮
while (b.find_element_by_class_name('code').get_attribute('href')!='javascript:void(0);'):
#如果出现验证码,使用tesseract进行尝试
print(b.find_element_by_class_name('W_btn_g'))
imgurl=b.find_element_by_class_name('code').get_attribute('href')
aun = yanzhengma(imgurl)
b.find_element_by_name('verifycode').send_keys(aun)
b.find_element_by_class_name('W_btn_g').click()
#如果实在过不去就手动输入验证码吧
#time.sleep(10)
time.sleep(4)
#等他跳转到淘宝页面
cookie = b.get_cookies()
#获取当前页面的cookie
jsonCookies = json.dumps(cookie)
with open('taobaocookie.json', 'w') as f:
f.write(jsonCookies)
if (cookie):
print('cookie获取成功')
b.quit()
cookie=''
with open('taobaocookie.json','r',encoding='utf-8') as f:
listCookies=json.loads(f.read())
cookie = [item["name"] + "=" + item["value"] for item in listCookies]
cookiestr = '; '.join(item for item in cookie)
#最后的这个cookiestr就是能直接用到爬虫文件中的字符串了