[数据采集]实验四

作业①

1.1题目

完整代码

要求:熟练掌握 scrapy 中 Item、Pipeline 数据的序列化输出方法;
使用Scrapy+Xpath+MySQL数据库存储技术路线爬取当当网站图书数据

1.2实现过程

1.2.1 观察html源代码

可以看到每一本书的全部信息存放在一个li标签

接着查看li标签内图书对应信息

1.2.2 代码实现

1、修改settings.py

  • 修改打印日志等级
# 修改打印日志等级 关掉一些你看了也看不懂的东西
LOG_LEVEL = 'ERROR'
  • 关闭遵循robots协议
# Obey robots.txt rules
ROBOTSTXT_OBEY = False    
  • 设置请求头
DEFAULT_REQUEST_HEADERS = {
    "user-agent" : "Mozilla/5.0 ......"
}
  • 打开ITEM_PIPELINES
ITEM_PIPELINES = {
   'dangdang.pipelines.DangdangPipeline': 300,
}

2、编写item.py

  • 保存我们需要爬取的信息,添加需要爬取的信息
class DangdangItem(scrapy.Item):
    # define the fields for your item here like:
    title = scrapy.Field()
    author = scrapy.Field()
    publisher = scrapy.Field()
    date = scrapy.Field()
    price = scrapy.Field()
    detail = scrapy.Field()
    datalist = scrapy.Field()

3、编写pipelines.py

  • 用于保存图书信息到数据库以及输出信息

4、编写PictureSpider

  • 根据html源代码使用Xpath解析页面,得到如下表达式
lis = selector.xpath("//li['@ddt-pit'][starts-with(@class,'line')]")
for li in lis:
    title = li.xpath("./a[position()=1]/@title").extract_first()
    price = li.xpath("./p[@class='price']/span[@class='search_now_price']/text()").extract_first()
    author = li.xpath("./p[@class='search_book_author']/span[position()=1]/a/@title").extract_first()
    date = li.xpath("./p[@class='search_book_author']/span[position()=last()-1]/text()").extract_first()
    publisher = li.xpath("./p[@class='search_book_author']/span[position()=last()]/a/@title").extract_first()
    detail = li.xpath("./p[@class='detail']/text()").extract_first()
  • 回调请求翻页
# 最后一页时link为None
link = selector.xpath("//div[@class='paging']/ul[@name='Fy']/li[@class='next']/a/@href").extract_first()
if link:
    url = response.urljoin(link)
    yield scrapy.Request(url=url, callback=self.parse)

1.3输出结果

MySQL数据库存储和输出格式如下:

作业②

2.1题目

完整代码

要求:熟练掌握 scrapy 中 Item、Pipeline 数据的序列化输出方法;
使用scrapy框架+Xpath+MySQL数据库存储技术路线爬取外汇网站招商银行网数据。

2.2实现过程

2.2.1 观察html源代码
  • 可以看到每个货币全部信息都存放在一个tr标签

  • 接着观察每个tr标签的内部内容,得到对应的信息

2.2.2 代码实现

1、修改settings.py

  • 内容同作业①

2、编写item.py

  • 保存我们需要爬取的信息,添加需要爬取的信息
class BankItem(scrapy.Item):
    Currency = scrapy.Field()  # 货币
    TSP = scrapy.Field()       # 现汇卖出价
    CSP = scrapy.Field()       # 现钞卖出价
    TBP = scrapy.Field()       # 现汇买入价
    CBP = scrapy.Field()       # 现钞买入价
    Time = scrapy.Field()
    datalist = scrapy.Field()

3、编写pipelines.py

  • 用于保存外汇网站信息到数据库以及输出信息
class BankPipeline:
    def process_item(self, item, spider):
        try:
            tply = "{0:^4}\t{1:^8}\t{2:<10}\t{3:<10}\t{4:<10}\t{5:<10}\t{6:<20}"
            print(tply.format("序号".ljust(4, half2full(' ')),      # 调整输出格式
                              "Currency".ljust(12, half2full(' ')),
                              "TSP".ljust(12, half2full(' ')),
                              "CSP".ljust(12, half2full(' ')),
                              "TBP".ljust(12, half2full(' ')),
                              "CBP".ljust(13, half2full(' ')),
                              "Time".ljust(20, half2full(' '))))
            count = 1
            for data in item['datalist']:
                print(tply.format(str(count).ljust(4, half2full(' ')),
                                  str(data[0]).ljust(8, half2full(' ')),
                                  half2full(str(data[1])).ljust(10, half2full(' ')),
                                  half2full(str(data[2])).ljust(10, half2full(' ')),
                                  half2full(str(data[3])).ljust(10, half2full(' ')),
                                  half2full(str(data[4])).ljust(10, half2full(' ')),
                                  str(data[5]).ljust(20, half2full(' '))))
                count += 1
            dbpath = "D:/网络爬虫/test.db"
            saveData2DB(item['datalist'], dbpath)        # 保存到数据库
        except Exception as err:
            print(err)
        return item

4、编写PictureSpider

  • 使用Xpath解析页面数据,得到如下表达式
trs = selector.xpath('//*[@id="realRateInfo"]/table/tr')
for tr in trs[1:]:      # 跳过第一行,因为第一行是标题
    Currency = tr.xpath("./td[1]/text()").extract_first()
    TSP = tr.xpath("./td[4]/text()").extract_first()
    CSP = tr.xpath("./td[5]/text()").extract_first()
    TBP = tr.xpath("./td[6]/text()").extract_first()
    CBP = tr.xpath("./td[7]/text()").extract_first()
    Time = tr.xpath("./td[8]/text()").extract_first()

2.3输出结果

MYSQL数据库存储和输出格式:

作业③

3.1题目

完整代码

要求:熟练掌握 Selenium 查找HTML元素、爬取Ajax网页数据、等待HTML元素等内容;
使用Selenium框架+ MySQL数据库存储技术路线爬取东方财富网“沪深A股”、“上证A股”、“深证A股”3个板块的股票数据信息。

3.2实现过程

3.2.1 观察html源代码
  • 可以看到每个股票都存放在一个tr标签

  • 观察每个tr标签可以得到每条股票的详细信息

  • 由于要求“沪深A股”、“上证A股”、“深证A股”3个板块的股票数据

  • 寻找“沪深A股”、“上证A股”、“深证A股”3个板块并进行点击跳转

3.2.2 代码实现

1、声明配置好的浏览器对象

chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--headless')
driver= webdriver.Chrome(chrome_options=chrome_options)
# 等待反应
wait = WebDriverWait(driver, 5)
url = 'http://quote.eastmoney.com/center/gridlist.html#hs_a_board'
driver.get(url)

2、找到板块,点击跳转(以“沪深A股”为例)

# 沪深A股
board1 = wait.until(
            EC.element_to_be_clickable((By.XPATH, '//*[@id="nav_hs_a_board"]/a'))
        )
board = driver.find_elements_by_xpath('//*[@id="nav_hs_a_board"]/a')[0].text
board1.click()
print('正在爬取', board)
get_products()              # 解析页面得到需要的内容

3、观察html源代码后使用Xpath解析页面

def get_products():
    time.sleep(3)   #不加可能会报错,因为还未来得及翻页就开始解析页面
    datalist = []
    items = driver.find_elements_by_xpath('//*[@id="table_wrapper-table"]/tbody/tr')
    try:
        for item in items:
            id = item.find_elements_by_xpath('./td[2]/a')[0].text            # 股票代码
            name = item.find_elements_by_xpath('./td[3]/a')[0].text          # 股票名称
            price = item.find_elements_by_xpath('./td[5]')[0].text           # 最新价
            change = item.find_elements_by_xpath('./td[6]/span')[0].text     # 涨跌额
            changeRate = item.find_elements_by_xpath('./td[7]/span')[0].text # 涨跌幅
            vol_num = item.find_elements_by_xpath('./td[8]')[0].text         # 成交量
            vol = item.find_elements_by_xpath('./td[9]')[0].text             # 成交额
            datalist.append([id,name,price,change,changeRate,vol_num,vol])
    except Exception as err:
        print(err)
  • 未加time.sleep之前执行代码会报错Message: stale element reference: element is not attached to the page document
  • 查找了原因,大概意思是说已经点击了翻页,但是还没有完成翻页,就开始解析页面,于是又爬了一次当前页,然后再要执行翻页时页面已经刷新了,前面找到的翻页元素已经过期了,导致无法执行
  • 加入time.sleep之后解决此问题

3.3输出结果

MySQL数据库存储和输出格式如下:

心得体会

  • 通过本次实验巩固了Scrapy框架的使用,更加熟悉翻页操作以及将数据保存到SQL的操作
  • 巩固了Selenium爬取网页的方法,了解如何通过模拟浏览器行为进行翻页、切换页面操作
posted @ 2021-11-10 14:59  penguin02  阅读(47)  评论(0编辑  收藏  举报